Go language Learning Notes-functions

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Function

Nesting (nested), overloading (overload), and default parameters are not supported (defaults parameter).
• No need to declare prototypes.
• Support for variable length parameters.
• Support for multiple return values.
• Named return parameters are supported.
• Supports anonymous functions and closures.
Use the keyword func to define the function, and the left brace cannot be another line.

func test(x,y int,s string) (int string) { //类型相同的相邻参数可合并。    n := x + y //多值返回必须用括号    return n, fmt.Sprintf(s,n)}

A function is a first class object that can be passed as a parameter. It is recommended that complex signatures be defined as function types for readability.

func test(fn func() int) int {    return fn()}type FormatFunc func(s string, x,y int) string //定义函数类型func format(fn FormatFunc, s string, x,y int) string {    return fn(s,x,y)}func main() {    s1 := test(func() int { return 100}) //直接将匿名函数当参数    s2 := format(func(s string, x, y int) string {        return fmt.Sprintf(s, x, y)    }, "%d, %d", 10, 20)    println(s1, s2)

Variable parameter

The argument is essentially a slice. There can be only one, and must be the last parameter bit.

func test(s string, n ...int) string {    var x int    for _, i := range n {        x += i    }    return fmt.Sprintf(s, x)}func main() {    println(test("sum: %d", 1, 2, 3))}

When you use a slice object to make a parameter, you must expand it.

func main() {    s := []int{1, 2, 3}    println(test("sum: %d",s...))}

return value

You cannot receive multiple return values with a container object. You can only use multiple variables, or "_" to ignore them. Multiple return values can be invoked directly as arguments to other functions.

func test() (int, int) {    return 1, 2}func add(x, y int) int {    return x + y}func sum(n ...int) int {    var x int    for _, i := range n {        x += i    }    return x}func main() {    println(add(test()))    println(sun(test()))}

A named return parameter can be considered a local variable similar to a formal parameter, and finally returned implicitly by return.

func add(x, y int) (z int) {    z = x + y    return}func main() {    println(add(1, 2))}

A named return parameter can be obscured by a local variable of the same name, which requires an explicit return.

func add(x, y int) (z int) {  {// 不能在一个级别,引发 "z redeclared in this block" 错误。      var z = x + y      // return // Error: z is shadowed during return      return z // 必须显式返回。  }}

The named return parameter allows defer deferred calls to be read and modified through closures.

func add(x, y int) (z int) {    defer func() {        z += 100    }()    z = x + y    return}func main() {    println(add(1, 2)) //输出:103}

The named return parameter is modified before the explicit return returns.

func add(x, y int) (z int) {    defer func() {        println(z)  //输出:203    }()    z = x + y    return z + 200}func main() {    println(add(1, 2))  //输出:203}

An anonymous function can be assigned to a variable, as a structure field, or in a channel. Closures replicate the original object pointers, which makes it easy to interpret the deferred reference phenomenon.

Deferred call

The keyword defer is used to register deferred calls. These calls are not executed until the RET, which is typically used to free resources or error handling. Multiple defer registrations, executed in FILO order. Even if a function or a deferred call has an error, these calls will still be executed.

Misuse of defer may cause performance problems, especially in a "cycle".

var log sync.Mutexfunc test() {    lock.Lock()    lock.Unlock()}func testdefer() {    lock.Lock()    defer lock.Unlock()}func BenchmarkTest(b *testging.B) {    for i := 0; i < b.N; i++ {        test()  }}func BenchmarkTestDefer(b *testging.B) {    for i := 0; i < b.N; i++ {        testdefer()  }}//输出:BenchmarkTest    50000000  43 ns/opBenchmarkTestDefer 20000000  128 ns/op

Error handling

Without a structured exception, panic throws an error and recover catches the error. Because the panic, recover parameter type is interface{}, any type object can be thrown. The capture function recover terminates the error only if it is called directly within the deferred call, otherwise it always returns nil. Any non-
The captured errors are passed out along the call stack.

func test() {  defer func() {        if err := recover(); err != nil {            println(err.(string)) // 将interface{}转型为string类型    }()    panic("panic erro!")}

In addition to using panic to throw a disruptive error, you can return an error type wrong object to represent the function call state. Standard library errors. New and FMT. The Errorf function is used to create an error object that implements the error interface. Determine the specific error type by judging the Error object instance. How to distinguish between using panic and error two ways?

The Convention is to use panic, which causes the critical process to appear unrecoverable errors, and the other uses error.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.