【问题标题】:What is the difference between := and = in Go?Go 中的 := 和 = 有什么区别?
【发布时间】:2016-07-30 12:04:55
【问题描述】:

我是 Go 编程语言的新手。

我在 Go 中发现了一些奇怪的东西:我认为它在 Python 中使用了 := 并替换了 =,但是当我在 Go 中使用 = 时它也可以工作。

:== 有什么区别?

【问题讨论】:

标签: go colon-equals


【解决方案1】:

在函数内部,:= 短赋值语句可以用来代替隐式类型的 var 声明。

例如:

package main

import "fmt"

func main() {
    var i, j int = 1, 2
    k := 3
    c, python, java := true, false, "no!"

    fmt.Println(i, j, k, c, python, java)
}

注意::=声明的变量只能在函数块内部使用。

【讨论】:

    【解决方案2】:

    := 是用于声明和初始化变量的“简短声明形式”。它确实对您分配的值进行类型推断以设置变量的类型。

    如果你试图用简短的声明形式给同一个作用域中的同一个变量赋值,编译器会抛出一个错误。

    注意在封闭范围内“隐藏”相同变量的简短声明形式(尤其是有错误时)

    = 在声明变量时需要 var 关键字,并且在变量名之后显式地声明变量的类型。实际上,您可以不使用 = 声明,因为 Go 对所有类型都有一个初始值(字符串初始化为“”,整数为 0,切片为空切片)。它也可以仅用于重新分配一个值,即

    var s string = "a string" // declared and initialized to "a string"
    s = "something else"      // value is reassigned
    
    var n int // declared and initialized to 0
    n = 3
    

    【讨论】:

      【解决方案3】:

      = 只是赋值

      := 是函数块(非全局)内新变量(至少一个新变量)的声明和初始化构造:

      var u1 uint32      //declare a variable and init with 0
      u1 = 32            //assign its value
      var u2 uint32 = 32 //declare a variable and assign its value at once
      //declare a new variable with defining data type:
      u3 := uint32(32)        //inside the function block this is equal to: var u3 uint32 = 32
      fmt.Println(u1, u2, u3) //32 32 32
      //u3 := 20//err: no new variables on left side of :=
      u3 = 20
      fmt.Println(u1, u2, u3) //32 32 20
      u3, str4 := 100, "str"        // at least one new var
      fmt.Println(u1, u2, u3, str4) //32 32 100 str
      

      【讨论】:

        【解决方案4】:

        = 是赋值。更多关于 Go 中的分配:Assignments

        =:= 之间的细微差别在于 = 用于变量声明时。

        Go 中变量声明的一般形式是:

        var name type = expression
        

        上面的声明创建了一个特定类型的变量,给它一个名字,并设置它的初始值。 type= expression 可以省略,但不能同时省略。

        例如:

        var x int = 1
        var a int
        var b, c, d = 3.14, "stackoverflow", true
        

        := 被称为 short variable declaration 并形成

        name := expression
        

        而名称的类型由表达式的类型决定

        注意::=是一个声明,而=是一个赋值

        因此,一个简短的变量声明必须声明至少一个新变量。这意味着一个简短的变量声明不一定在其左侧声明所有变量,当其中一些变量已经在同一个词法块中声明时,:= 就像对这些变量的赋值

        例如:

         r := foo()   // ok, declare a new variable r
         r, m := bar()   // ok, declare a new variable m and assign r a new value
         r, m := bar2()  //compile error: no new variables
        

        此外,:= 可能只出现在函数内部。在某些上下文中,例如“if”、“for”或“switch”语句的初始化器,它们可用于声明局部临时变量。

        更多信息:

        variable declarations

        short variable declarations

        【讨论】:

        • so inside { } using := 意味着声明新变量,即使在封闭的 { } 之外有同名的相同变量?
        • 是的,它是一个新的。 {} 是一个词法块,不同的词法块是不同的范围。但是在实践中使用相同的名称通常不是一种好的风格。 @鲸鱼管家
        【解决方案5】:

        我花时间找出我犯的一个错误,它可以帮助您澄清:== 之间的区别。 考虑以下代码:

        type mystruct struct {
            a int
            arr []int
        }
        
        func main() {   
            m := mystruct{}
            m.arr := make([]int, 5) //compilation error because m.arr is already declared.
            m.arr = make([]int, 5)  //compiles
        
        }
        

        【讨论】:

          【解决方案6】:

          = 用作静态类型。

          := 用作动态类型。

          示例:

          var a = 30   # statically typed and is a compile time check
          
          b := 40      # dynamically checked. 
          

          【讨论】:

            【解决方案7】:

            还要注意range 子句中:== 的区别。以下示例改编自spec

            迭代变量可以通过“范围”子句使用短变量声明 (:=) 的形式来声明。在这种情况下,它们的类型被设置为各自迭代值的类型,它们的范围是“for”语句的块;它们在每次迭代中重复使用。如果迭代变量在“for”语句外部声明,则在执行后它们的值将是last迭代的值。

            = range ...:

            i := 2
            x = []int{3, 5, 7}
            for i, x[i] = range x {  // i,x[2] = 0,x[0]
                break
            }
            // now i == 0 and x == []int{3, 5, 3}
            
            var (key string; val interface{})
            m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
            for key, val = range m {
                h(key, val)
            }
            // key == last map key encountered in iteration (note order of map iteration is random)
            // val == map[key]
            

            := range ...:

            var a [10]string
            for i, s := range a {
                // type of i is int, type of s is string
                // s == a[i]
                someFunction(i, s)
            }
            // i and s are no longer accessible here.
            
            for i := range a { // roughly equivalent to `for i := 0; i < len(a); i++`
                someFunction(i, a[i])
            }
            
            for _, s := range a {
                anotherFunc(s)
            }
            // Above is roughly equivalent to:
            {
                var s string
                for i := 0; i < len(a); i++ {
                     s = a[i]
                     anotherFunc(s)
                }
            }
            // s not accessible here
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2019-12-14
              • 2016-12-13
              • 2014-02-24
              • 1970-01-01
              • 2023-02-09
              • 2017-01-04
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多