Go语言学习指南(第一部分)

发表时间: 2023-11-12 22:52

1、左大括号必须与func关键字位于同一行而不是独占一行,这是Go语言唯一允许的大括号放置风格。

package mainimport "fmt"func main() { // 此大括号必须这样放置    fmt.Print("Hello, World")}

2、Printf接受的第一个参数总是文本,第二个参数则是表达式,而文本中包含的格式化变量%v则会在之后被替换成表达式的值。它还能够调整文本的对其位置,当宽度为正数时空格将被填充值文本左边,而当宽度为负数时空格将被填充至文本右边。

package mainimport "fmt"func main() {    fmt.Printf("My weight on the surface of Mars is %v lbs", 136.0*0.3783)		fmt.Printf("%-15v|%4v\n", "SpaceX", 100)}// My weight on the surface of Mars is 51.4488 lbs// SpaceX         | 100

3、const和var分别用于声明常量和变量

package mainimport "fmt"func main() {    const lightSpeed = 299792 // km/s    var distance = 56000000   // km    fmt.Println(distance/lightSpeed, "seconds") // 186}

4、声明变量或者常量的时候,也可以一次声明一组变量或者在同一行中声明多个变量。

package mainimport "fmt"func main() {    var (       distance   = 56000000       lightSpeed = 299792    )    //var distance, lightSpeed = 56000000, 299792    fmt.Println(distance / lightSpeed)}

5、可以使用如下age++或者weight *= 0.3783这样简短的方式执行常见的算术运算(Go并不支持++age这种前置增量操作)

package mainfunc main() {    var weight = 136.0    weight *= 0.3783    var age = 18    age++}

6、向rand包的Intn函数传入数字可以返回一个伪随机数

package mainimport (    "fmt"    "math/rand")func main() {    var num = rand.Intn(10) + 1    fmt.Println(num) // 生成一个1~10的伪随机数}

7、对Go来说,true是唯一的真值,而false则是唯一的假值。比较两个值是得出true或false的另一种方式。

package mainimport (	"fmt"	"strings")func main() {	var command = "walk outside"	fmt.Println(strings.Contains(command, "outside")) // true	var age = 33	fmt.Println(age < 18) // false}

8、使用if实现分支判断

package mainimport "fmt"func main() {    var command = "east"    if command == "east" { // comand == "east"不需要小括号       fmt.Println("Direction east")    } else {       fmt.Println("Other direction")    }}

9、Go也采用短路逻辑:如果位于| |运算符之前的条件为真,那么位于| |运算符之后的条件就可以忽略,没有必要再对其进行求值。

10、在Java等语言中,下降是switch语句各个分支的默认行为,而Go对此采取了更为谨慎的做法,需要显示地使用fallthrough关键字才会引发下降。

11、使用循环实现重复执行

package mainimport "fmt"func main() {    var count = 10    for count > 0 {       fmt.Println(count)       count--    }}

12、猜数字游戏

package mainimport (    "fmt"    "math/rand")func main() {    secretNumber := rand.Intn(100) + 1    fmt.Println("猜一个1到100的数字!")    tries := 0    for {       var guess int       fmt.Print("请输入你的猜测:")       _, err := fmt.Scan(&guess)       tries++       if err != nil {          fmt.Println("请输入有效数字!")          continue       }       if guess < secretNumber {          fmt.Println("太小了")       } else if guess > secretNumber {          fmt.Println("太大了")       } else {          fmt.Printf("恭喜你猜对了!尝试了%d次", tries)          break       }    }}

13、简短声明比var关键字流行的多,可以用在一些无法使用var关键字的地方(包作用域在声明时不允许使用简短声明)

14、switch分支的作用域是唯一一种无需使用大括号标识的作用域

15、Go语言拥有两种浮点类型,其中默认的浮点类型为float64,每个64为的浮点数需要占用8字节内存;另一种浮点类型是float32,它占用的内存只有float64类型的一半,但它提供的精度不如float64,要使用float32浮点数,必须在声明时指定变量类型

package mainimport (    "fmt"    "math")func main() {    var pi64 = math.Pi    var pi32 float32 = math.Pi    fmt.Println(pi64) // 3.141592653589793    fmt.Println(pi32) // 3.1415927  	  	// 打印浮点类型    var num = 1.0 / 3    fmt.Println(num) // 0.3333333333333333    fmt.Printf("%4.3f\n", num) // 0.333    fmt.Printf("%05.2f", num) // 00.33}

16、如下,浮点数也许并不是表示金钱的最佳选择,解决这一问题的另一种做法是使用整数类型存储分的数量

package mainimport "fmt"func main() {    a := 0.1    a += 0.2    fmt.Println(a) // 0.30000000000000004}

17、为了避免如下问题,可以不直接比较两个浮点数,而是计算出他们之间的差,然后通过判断这个差的绝对值是否足够小来判断两个浮点数是否相等

package mainimport "fmt"func main() {    a := 0.1    a += 0.2    fmt.Println(a == 0.3) // false  	fmt.Println(math.Abs(a-0.3) < 0.0001) // true}

18、Go提供了5种有符号整数类型(int、int8、int16、int32、int64),5种无符号整数类型(uint、uint8、uint16、uint32、uint64),在进行类型推断的时候总是会选择int类型作为整数值的类型。int和uint类型会根据目标硬件选择最合适的位长,另8种无关计算机架构。

19、如下,为了避免在Printf函数中重复使用同一个变量两次,可以将[1]添加到第二个格式化变量%v中。

package mainimport "fmt"func main() {    a := 2023    fmt.Printf("Type %T for %v\n", a, a) // Type int for 2023    b := 3.14    fmt.Printf("Type %T for %[1]v", b) // Type float64 for 3.14}

20、Go语言中的16进制数字

package mainimport "fmt"func main() {    var red, green, blue uint8 = 0x00, 0x8d, 0xd5    fmt.Printf("#%02x%02x%02x", red, green, blue) // #008dd5  	// 格式化变量%02x跟格式化变量%v和%f一样,通过数字2指定了格式化输出的最小数字数量  	// 通过数字0启用了格式化的0填充功能}

21、整数回绕现象:例如,8位无符号整数uint8类型的取值范围是0~255,而针对该类型的增量操作在结果超过255时将回绕至0

package mainimport "fmt"func main() {    var red uint8 = 255    red++    fmt.Println(red) // 0  	// 最简单的避免回绕的方法就是选用一种足够长的整数类型,使它能够容纳你想要存储的值}

22、如果没有显示地为包含指数的数值变量指定类型,那么Go将推断其类型为float64。

23、如下,创建big.Int的两种方式

package mainimport (    "fmt"    "math/big")func main() {    lightSpeed := big.NewInt(299792) // 第一种    distance := new(big.Int)    distance.SetString("24000000000000000000", 10) // 第二种    t := new(big.Int)    t.Div(distance, lightSpeed)    fmt.Println(t) // 80055505150237}

24、Go语言不会为常量推断类型,而是直接将其标识为无类型;针对常量和字面量的计算将在编译时而不是程序运行时;尽管Go编译器使用big包处理无类型的数值常量,但常量与big.Int值是无法互换的。