10.functions

Return multiple values

// Sample program to show how functions can return multiple values while using
// named and struct types.
package main

import (
    "encoding/json"
    "fmt"
)

// user is a struct type that declares user information.
type user struct {
    Id   int
    Name string
}

// retrieveUser retrieves the user document for the specified
// user and returns a pointer to a user type value.
// retrieveUser检索指定的用户文档。
//用户返回一个指向用户类型值的指针。
func retrieveUser(name string) (*user, error) {
    // Make a call to get the user in a json response.
    r, err := getUser(name)
    if err != nil {
        return nil, err
    }

    // Unmarshal the json document into a value of
    // the user struct type.
    var u user
    err = json.Unmarshal([]byte(r), &u)
    return &u, err
}

// GetUser simulates a web call that returns a json
// document for the specified user.
// GetUser模拟返回json的web调用。
//指定用户的文件。
func getUser(name string) (string, error) {
    response := `{"id":1432, "name":"sally"}`
    return response, nil
}

func main() {
    // Retrieve the user profile.
    u, err := retrieveUser("sally")

    if err != nil {
        fmt.Println(err)
        return
    }

    // Display the user profile.
    fmt.Printf("%+v\n", *u)
}

/*
{Id:1432 Name:sally}

*/

Blank identifier 空白标识符

// Sample program to show how we can use the blank identifier to
// ignore return values.
// 示例程序演示如何使用空白标识符。
// 忽略返回值。
package main

import (
    "encoding/json"
    "errors"
    "fmt"
)

// user is a struct type that  declares user information.
type user struct {
    ID   int
    Name string
}

// updateStats provIDes update stats.
type updateStats struct {
    Modified int
    Duration float64
    Success  bool
    Message  string
}

func main() {
    // Declare and initialize a value of type user.
    u := user{
        ID:   1432,
        Name: "Betty",
    }

    // Update the user Name. Don‘t care about the update stats. 更新用户名。不要在意更新stats。
    if _, err := updateUser(&u); err != nil {
        fmt.Println(err)
        return
    }

    // Display the update was Successful.
    fmt.Println("Updated user record for ID", u.ID)
}

// updateUser updates the specified user document.
func updateUser(u *user) (*updateStats, error) {
    // response simulates a JSON response.
    response := `{"Modified":1, "Duration":0.005, "Success" : true, "Message": "updated"}`

    // Unmarshal the json document into a value of
    // the userStats struct type.
    var us updateStats
    if err := json.Unmarshal([]byte(response), &us); err != nil {
        return nil, err
    }

    // Check the update status to verify the update
    // was Successful.
    if us.Success != true {
        return nil, errors.New(us.Message)
    }

    return &us, nil

}

/*
Updated user record for ID 1432
*/

Redeclarations

// From Spec:
// a short variable declaration may redeclare variables provided they
// were originally declared earlier in the same block with the same
// type, and at least one of the non-blank variables is new.

// Sample program to show some of the mechanics behind the
// short variable declaration operator redeclares.
//从规范:
//一个简短的变量声明可以重新声明提供的变量。
//最初是在同一块区域以相同的方式声明的。
//类型,至少其中一个非空变量是新的。

//示例程序展示了一些背后的机制。
//短期变量声明操作符声明。

package main

import "fmt"

// user is a struct type that declares user information.
type user struct {
    id   int
    name string
}

func main() {
    // Declare the error variable.
    var err1 error

    // The short variable declaration operator will
    // declare u and redeclare err1.
    u, err1 := getUser()
    if err1 != nil {
        return
    }
    fmt.Println(u) // &{1432 Tomcat}

    // The short variable declaration operator will
    // redeclare u and declare err2.
    u, err2 := getUser()
    if err2 != nil {
        return
    }

    fmt.Println(u)
    // &{1432 Tomcat}

}

// getUser returns a pointer of type user.
func getUser() (*user, error) {
    return &user{1432, "Tomcat"}, nil
}

Anonymous Functions/Closures 匿名和defer

// Sample program to show how anonymous functions and closures work.
package main

import "fmt"

func main() {
    var n int
    // Declare an anonymous function and call it.
    func() {
        fmt.Println("Direct:", n)
    }()
    /*
        Direct: 0
    */

    // Declare an anonymous function and assign it to a variable.
    f := func() {
        fmt.Println("Variable:", n)
    }

    // Call the anonymous function through the variable.
    f()
    /*
        Variable: 0
    */

    // Defer the call to the anonymous function till after main returns. 在主返回之后,将调用延迟到匿名函数。
    defer func() {
        fmt.Println("Defer 1:", n)
    }()

    // Set the value of n to 3 before the return.
    n = 3

    // Call the anonymous function through the variable.
    f()

    // Defer the call to the anonymous function till after main returns.
    defer func() {
        fmt.Println("Defer 2:", n)
    }()

}

/*  说明后进先执行 从下往上
Direct: 0
Variable: 0
Variable: 3
Defer 2: 3
Defer 1: 3
*/

恢复?

// Sample program to show how to recover from panics.
package main

import (
    "fmt"
    "runtime"
)

func main() {

    // Call the testPanic function to run the test.
    if err := testPanic(); err != nil {
        fmt.Println("Error:", err)
    }
}

// testPanic simulates a function that encounters a panic to
// test our catchPanic function.
func testPanic() (err error) {

    // Schedule the catchPanic function to be called when
    // the testPanic function returns.
    defer catchPanic(&err)

    fmt.Println("Start Test")

    // Mimic a traditional error from a function.
    err = mimicError("1")

    // Trying to dereference a nil pointer will cause the
    // runtime to panic.
    var p *int
    *p = 10

    fmt.Println("End Test")
    return err
}

// catchPanic catches panics and processes the error.
func catchPanic(err *error) {

    // Check if a panic occurred.
    if r := recover(); r != nil {
        fmt.Println("PANIC Deferred")

        // Capture the stack trace.
        buf := make([]byte, 10000)
        runtime.Stack(buf, false)
        fmt.Println("Stack Trace:", string(buf))

        // If the caller wants the error back provide it.
        if err != nil {
            *err = fmt.Errorf("%v", r)
        }
    }
}

// mimicError is a function that simulates an error for
// testing the code.
func mimicError(key string) error {
    return fmt.Errorf("Mimic Error : %s", key)
}

/*
Start Test
PANIC Deferred
Stack Trace: goroutine 1 [running]:
main.catchPanic(0xc04202bf08)
*/

练习

// Declare a struct type to maintain information about a user. Declare a function
// that creates value of and returns pointers of this type and an error value. Call
// this function from main and display the value.
//
// Make a second call to your function but this time ignore the value and just test
// the error value.

//声明一个结构类型以维护有关用户的信息。声明一个函数
//它会创建并返回该类型的指针和错误值。调用
//该函数从main函数中显示值。

//再次调用你的函数,但这一次忽略值,只测试。
//错误的值。
package main

import "fmt"

// user represents a user in the system.
type user struct {
    name  string
    email string
}

// newUser creates and returns pointers of user type values.
func newUser() (*user, error) {
    return &user{"Bill", "[email protected]"}, nil
}

func main() {

    // Create a value of type user.
    u, err := newUser()
    if err != nil {
        fmt.Println(err)
        return
    }

    // Display the value.
    fmt.Println(*u)

    // Call the function and just check the error on the return.
    _, err = newUser()
    if err != nil {
        fmt.Println(err)
        return
    }

}

/*
{Bill [email protected]}
*/

原文地址:https://www.cnblogs.com/zrdpy/p/8591955.html

时间: 2024-11-05 17:46:34

10.functions的相关文章

[转].net core 通过ViewComponent封装控件 左侧菜单

本文转自:http://www.cnblogs.com/BenDan2002/p/6224816.html 我们在.net core中还使用了ViewComponent方式生成控件.ViewComponent也是asp.net core的新特性,是对页面部分的渲染,以前PartialView的功能,可以使用ViewComponent来实现. View Component包含2个部分,一个是类(继承于ViewComponent),和它返回的结果Razor视图(和普通的View视图一样). 我们还是

A Byte of Python

1. Welcome 2. Dedication 3. Preface 4. Introduction 5. Installation 6. First Steps 7. Basics 8. Operators and Expressions 9. Control Flow 10. Functions 11. Modules 12. Data Structures 13. Problem Solving 14. Object Oriented Programming 15. Input and

20.文件系统——使用RPM安装、卸载、查询、升级和校验软件包

一.使用RPM安装软件包 rpm安装软件包,使用的选项是-i或者是--install,格式如下: rpm -i|--install /Path/To/RPM_File 如果要显示安装时的信息,可以使用-v.-vv.-vvv选项,其中v的个数用来表示显示信息的详细级别. 如果要以哈希码(#,一个#表示2%)的形式显示安装进度,可以使用-h选项. 通常情况下上述三个选项会组合起来使用. 下面来演示一下rpm包的安装过程: [[email protected]]# rpm -ivh zsh-4.3.1

Zinc

ZINC 0.A.0.0 Table of contents I. Why Zinc? C-like syntax Less verbosity Readability Segregation Structured programming vJass interoperability Do not "live a lie" Rigidity Fix vJass mistakes Anonymous functions II. Because it is good for your br

Linux 基础 —— RPM

http://liaoph.com/linux-rpm/ 这篇文章主要讲 RPM 软件包管理器的使用. 软件包的演变史 最早期时,软件包是一些可以运行的程序组成的集合,可能还要加上若干配置文件和动态库.例如,程序员将针对某个平台编译好的二进制文件.程序所依赖的动态库文件(如 .so 和 .dll 为扩展名的文件)以及配置文件复制到一个目录中,这个目录就可以称为一个软件包. 为了保证使用的软件包能够方便且快速地复制到别的机器上, 人们开始选用压缩文件的方式来封装软件包. 比如通过 tar 或者 g

Linux系统程序包的管理功能相关命令rpm与yum的使用

一.软件包管理核心功能 1.软件包制作 2.包管理器:打包,安装.升级.卸载.查询及校验 3.工具:rpm .deb 4.程序包的组成部分: 二进制程序:/bin, /sbin,/ /usr/bin, /usr/sbin, 库文件:/lib64, /usr/lib64 配置文件:/etc 帮助文件:manual, info 5.rpm包管理 rpm:数据库  /var/lib/rpm rpmbuild:建立软件管理数据库 rpm包默认为二进制格式,有rpm包作者下载源码程序,编译完成后,制作成r

Linux的程序包管理

软件包管理工具:rpm.yum POSIX:Portable Openratin System  跨平台调用 API:兼容,意味开发库兼容,因此,源代码可跨平台 ABI:兼容,编译后的程序可以跨平台 库为函数,function 库:可执行程序,本身不能作为程序执行入口,但可以被调用 是编译好的二进制格式 程序的过程:预编译.编译.汇编.链接 静态链接:将库包含在程序中 动态链接:dll,so(shared object) 编译:源代码翻译成cpu指令集的过程 注意: os平台:编译好的应用程序必

19.分屏查看命令 more命令

more命令: 特点:翻屏至文件尾部后自动退出: more 命令类似 cat ,不过会以一页一页的形式显示,更方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会往回(back)一页显示,而且还有搜寻字串的功能(与 vi 相似),使用中的说明文件,请按 h . 该命令一次显示一屏文本,满屏后停下来,并且在屏幕的底部出现一个提示信息,给出至今己显示的该文件的百分比:--More--(XX%)可以用下列不同的方法对提示做出回答: 按Space键:显示文本的下一屏

ue4 material custom node - global function and method

在ue4 material中定义全局函数 1. 背景 原文unreal-engine-4-custom-shaders-tutorial 中,提出了一种在material生成的hlsl文件中定义全局函数的方法,记录到这里以备复习. ue4 材质中的custom节点是用来使用hlsl代码的地方.一般来说都是直接编辑逻辑,最后添加return返回.类似这样: 1 float4 color = {1,0,0,1}; 2 return color; 使用ue4材质 menu window->hlsl s