码迷,mamicode.com
首页 > 其他好文 > 详细

10.functions

时间:2018-03-17 19:45:31      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:hat   reference   ons   ali   type   tip   turn   变量   有关   

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", "bill@ardanlabs.com"}, 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 bill@ardanlabs.com}
*/

10.functions

标签:hat   reference   ons   ali   type   tip   turn   变量   有关   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!