ch5、变量、常量以及与其它语言的差异

ch5、变量、常量以及与其它语言的差异

1、编写测试程序

1.1、源码文件以_test结尾:***_test.go;

1.2、测试方法名以Test开头:func Testxxx(t *testing.T) {…},首字母大写代表包外可以访问

  • t.Log() 可以直接打印结果

  • cmd运行命令:go test -v ***_test.go (不加 -v 会没有对应的测试结果)。

2、变量声明、初始化

// 标准格式
var 变量名称 数据类型 = 值;
// 自动推到类型格式
var 变量名称 = 值;
// 简短格式(golang官方推荐格式)
变量名称 := 值;

2.1 、声明方法

// 变量声明、初始化方法一
var a int = 1
var b int = 1

// 变量声明、初始化方法二
var (
a int = 1
b = 1
)

// 变量声明、初始化方法三,推荐使用该方法
a := 1    // := 表示自动推断变量类型
b := 1

// 变量声明、初始化方法四
var a int // 先声明后使用,一般是全局变量使用
var b int
a = 1
b = 1

2.2、与其他编程语言的差异:

赋值可以进行自动类型推断;

在一个赋值语句中可以对多个变量进行赋值。

2.3、使用简短格式:=赋值的注意点

  • 简短模式的含义是定义的同时初始化
package main
import "fmt"
func main() {
	num := 10
	num := 20 // 编译报错, 重复定义
	fmt.Println("num = ", num)
}
  • 一定不要把:=当做赋值运算符来使用
package main
import "fmt"
var num = 10 // 定义一个全局变量
func main() {
	num := 20 // 定义一个局部变量
	fmt.Println("num = ", num)
        test()
}
func test() {
	fmt.Println("num = ", num) // 还是输出10
}
  • :=只能用于定义局部变量,不能用于定义全局变量
package main
import "fmt"
num := 10 // 编译报错
func main() {
	fmt.Println("num = ", num)
}
  • 使用:=定义变量时,不能指定var关键字和数据类型
package main
import "fmt"
func main() {
	//var num int := 10 // 编译报错
	//var num := 10 // 编译报错
	num int := 10 // 编译报错
	fmt.Println("num = ", num)
	fmt.Println("num = ", num)
}
  • 变量组中不能够使用:=
package main
import "fmt"
func main() {
	var(
		num := 10 // 编译报错
	)
	fmt.Println("num = ", num)
}
  • 通过:=同时定义多个变量, 必须给所有变量初始化
package main
import "fmt"
func main() {
	//num1, num2 := 666, 888 // 正确
	num1, num2 := 666 // 报错
	fmt.Printf("%d, %d\n", num1, num2)
}
  • 通过:=同时定义多个变量, 只要任意一个变量没有定义过,都会做退化赋值操作

发生退化赋值:

package main
import "fmt"
func main() {
	// 定义一个变量num1
	num1 := 10
	// 同时定义两个变量num1和num2, 由于num2从来没有定义过,
	// 所以对于num1来说:=退化为赋值运算符, 而对于num2来说:=仍然是定义+赋值
	num1, num2 := 20, 30
	fmt.Println("num1 = ", num1)
	fmt.Println("num2 = ", num2)
}

不会发生退化赋值:

package main
import "fmt"
func main() {
	num1 := 10
	num2 := 20
	// 报错, 因为num1,和num2都已经被定义过
	// 至少要有任意一个变量没有被定义过,才会退化赋值
	num1, num2 := 30, 40
	fmt.Println("num1 = ", num1)
	fmt.Println("num2 = ", num2)
}
  • 定义的局部变量或者导入的包没有被使用, 那么编译器会报错,无法编译运行,但是定义的全局变量没有被使用,编译器不会报错, 可以编译运行

3、go语言交换两个变量的值

func TestExchange(t *testing.T) {
a := 1
b := 2
a, b = b, a   // 和python保持了一致
t.Log(a, b)
}

4、常量定义

4.1、使用const声明(与C语言一致)

const 常量名称 数据类型 = 值or const 常量名称 = 值

4.2、与其他语言的差别在于简化了连续的赋值。

在常量组中, 如果上一行常量有初始值,但是下一行没有初始值, 那么下一行的值就是上一行的值

  package main
  import "fmt"
  func main() {
    const (
    	num1 = 998
    	num2 // 和上一行的值一样
    	num3 = 666
    	num4 // 和上一行的值一样
    	num5 // 和上一行的值一样
    )
    fmt.Println("num1 = ", num1) // 998
    fmt.Println("num2 = ", num2) // 998
    fmt.Println("num3 = ", num3) // 666
    fmt.Println("num4 = ", num4) // 666
    fmt.Println("num5 = ", num5) // 666
  
    const (
    	num1, num2 = 100, 200
    	num3, num4  // 和上一行的值一样, 注意变量个数必须也和上一行一样
    )
    fmt.Println("num1 = ", num1)
    fmt.Println("num2 = ", num2)
    fmt.Println("num3 = ", num3)
    fmt.Println("num4 = ", num4)
  }

4.3、枚举常量

  • Go语言中没有C语言中明确意义上的enum定义, 但是可以借助iota标识符来实现枚举类型,Go语言实现枚举格式

    const(
      枚举元素1 = iota
      枚举元素2 = iota
      ... ...
    )
    
    • 利用iota标识符标识符实现从0开始递增的枚举

      package main
      import "fmt"
      func main() {
      	const (
      		male = iota
      		female = iota
      		yao = iota
      	)
      	fmt.Println("male = ", male) // 0
      	fmt.Println("male = ", female) // 1
      	fmt.Println("male = ", yao) // 2
      }
      
    • iota注意点:

      • 在同一个常量组中,iota从0开始递增, 每一行递增1
      • 在同一个常量组中,只要上一行出现了iota,那么后续行就会自动递增
      package main
      import "fmt"
      func main() {
        const (
        	male = iota // 这里出现了iota
        	female // 这里会自动递增
        	yao
        )
        fmt.Println("male = ", male) // 0
        fmt.Println("male = ", female) // 1
        fmt.Println("male = ", yao) // 2
      }
      
      • 在同一个常量组中,如果iota被中断, 那么必须显示恢复
      package main
      import "fmt"
      func main() {
        const (
        	male = iota 
        	female = 666 // 这里被中断, 如果没有显示恢复, 那么下面没有赋值的常量都和上一行一样
        	yao
        )
        fmt.Println("male = ", male) // 0
        fmt.Println("male = ", female) // 666
        fmt.Println("male = ", yao) // 666
      }
      
      package main
      import "fmt"
      func main() {
        const (
        	male = iota 
        	female = 666 // 这里被中断
        	yao = iota // 这里显示恢复, 会从当前常量组第一次出现iota的地方开始,每一行递增1, 当前是第3行,所以值就是2
        )
        fmt.Println("male = ", male) // 0
        fmt.Println("male = ", female) // 666
        fmt.Println("male = ", yao) // 2
      }
      
      • iota也支持常量组+多重赋值, 在同一行的iota值相同
      package main
      import "fmt"
      func main() {
        const (
          a, b = iota, iota
          c, d = iota, iota
        )
        fmt.Println("a = ", a) // 0
        fmt.Println("b = ", b) // 0
        fmt.Println("c = ", c) // 1
        fmt.Println("d = ", d) // 1
      }
      
      • iota自增默认数据类型为int类型, 也可以显示指定类型
      package main
      import "fmt"
      func main() {
      const (
          male float32 = iota // 显示指定类型,后续自增都会按照指定类型自增
          female
          yao
      )
      fmt.Printf("%f\n", male) // 0.0
      fmt.Printf("%f\n", female) // 1.0
      fmt.Printf("%f\n", yao) // 2.0
      fmt.Println("male = ", reflect.TypeOf(female)) // float32
      }
      

5、标识符

  • Go语言中_单独作为标识符出现时, 代表空标识符, 它对应的值会被忽略;
  • 规则必须遵守, 规范不一定要遵守, 但是建议遵守;
  • Go语言的命名规范和C语言一样, 都是采用驼峰命名, 避免采用_命名:
    • 驼峰命名: sendMessage / sayHello
    • _命名: send_message / say_hello

你可能感兴趣的:(Go学习记录,c语言,golang,开发语言)