One day _go learn from the mistakes of the basic one

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

When writing the go code, there were some errors, and I sorted out these common mistakes. First, let oneself re-understand Golang, carry out insufficient study. The second is to share it so that more people know Golang.

Short declaration use

A short declaration can only appear inside a function.

func(){   a := 10}()

A re-declaration of the short Declaration.
Official explanation: Unlike regular variable declarations, a short variable declaration may redeclare variables provided they wer E originally declared earlier in the same block (or the parameter lists if the block was the function body) with the same t Ype, and at least one of the Non-blank variables are new. As a consequence, redeclaration can only be appear in a multi-variable short declaration. Redeclaration does not introduce a new variable; It just assigns a new value to the original.
Translation: Unlike regular variable declarations, short variable declarations can re-declare variables if they are originally declared in the same block (such as a function body) with the same type and at least one non-null variable. Therefore, a re-declaration can only appear in a multivariate short declaration. Re-declaring that new variables are not introduced; It simply assigns a new value to the original value.

func main() {      c:=10      c:=23  //----上面短声明使用错误,重声明只能出现在多变量短声明中---    a := 10    fmt.Println(&a, a)    a, b := 15, 39    fmt.Println(&a, a, b)}

Print the results.

 0xc082002278 10 0xc082002278 15 39

The short declaration scope.


Keng
    func() (err error) {        a, err := 1, errors.New(" a error") // a是新创建变量,err是被赋值        if err != nil {            return // 正确返回err        }              //  ------------------------------------------------        if b, err := 2,  errors.New("b error"); err != nil { // 此刻if语句中err被重新创建            return     // if语句中的err覆盖外面的err,导致编译                      //  错误 (err is shadowed during return。)        } else {            fmt.Println(b)        }        return    }()

The above code, because: = caused by the scope of the cause of the error, you need to note that if: = left a variable in the outer scope has been defined, the assignment in the inside will cause the external variable to be masked, create a new variable in the current scope to use. If you need to change an external variable to assign a value =.

String efficiency

Strings in the Go language are immutable (similar to Java and C #). Using the form of a + = B connection string is inefficient, especially within a loop. This can result in a lot of memory overhead and copying. You should use a character array instead of a string, or write the contents of the string to a cache. As follows:

  str := func() string {      var b bytes.Buffer      for i := 0; i < 10; i++ {          b.WriteString("wuxiao" + i)      }      return b.String()  }()

Defer use

Defer delay call.


Feeling very tall on

When a function calls a function (variable) with the keyword defer, the defer function (variable) is deferred until the current function is about to return. For example:

func(){     a := 1     defer fmt.Println("deder print:", a)     a++     fmt.Println("a add print:", a)}()

It is important to note that if there are parameters in a function that uses the DEFER keyword, this parameter is defined.
Print the results.

  a add print: 2  deder print: 1

So defer fmt.Println("deder print:", a) when called, the value of a is already determined, and all a equals 1.

There is an interesting example that will deepen the understanding of defer.

func add(x int) int {    return x + x}func result(x int) (r int) {    defer func() {        r += x    }()    return add(x)}func main() {    fmt.Println(result(3))}

It is important to emphasize that the order in which the DEFER keyword function calls is executed is after the outer function sets the return value and will be returned before.
All printing results are 9.


So young.

The previous write code made a mistake as follows:

  for _, file := range files {     if f, err = os.Open(file); err != nil {         return     }     defer f.Close()     // 假设处理文件     f.doSomething(data) }

The code is no problem ah, no mistakes AH!!!
No, will cause the loop end of the defer has not been executed, the file did not close in time!

  for _, file := range files {     if f, err = os.Open(file); err != nil {         return     }     // 假设处理文件     f.doSomething(data)     //正确做法     f.Close() }

Interface type Use

type tester interface {    test()}func testFun(n *tester) {    n.test() // 编译错误:n.test未定义}

Oh, why???

A lot of data, interface type This is a pointer, all cannot use a pointer to an interface type.


Don't understand


In order to better understand interface, we use a demo to understand what interface memory does.

type tester interface{      test()}func testing() tester {    var t tester    return t}func main(){    tester := testing()    if tester == nil    //执行结果true}

Interface Memory Status

A simple view of the interface source code corresponding to the initialization of interface memory will create tab and data.

type iface struct {    tab *itab    data unsafe.Pointer}

tab represents an interface table, which is a structure that holds information about the interface and the underlying type:

type itab struct {    inter *interfacetype    _type *_type    link *itab    bad int32    unused int32    fun [1]uintptr // variable sized}

From the above memory and source code can be seen interface is really pointer type
There is also a pit that needs to be mapped with the above memory map to interface内存状态 learn, code and memory state diagram as follows:

type tester interface{      test()}func testing() tester {    var t *testIml //实现tester接口    return t}func main(){    tester := testing()    if tester == nil    //执行结果false}

Memory state diagram After interface implementation


Summarize:

    • From the internal structure of these two interfaces we can out, if the implementation of the interface of the variable non-null judgment will appear its own unwanted results, and then avoid making mistakes.
Related Article

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.