极限转GO | GO基础

50 阅读3分钟

Java选手极限速通Go

一、GO环境配置

因为本人是 mac 系统,通过 brew 快速安装

brew install go

配置一下环境变量, 在 ~/.zshrc 或自己其他的配置文件中添加

export PATH=$PATH:$HOME/go/bin

还有一些代理的配置,这里不再赘述

二、变量与常量

Go 的变量有三种声明方式:

  1. var a int
  2. var a = 1 类型自动推断
  3. a := 1

但是例如 a := 1 这种方式无法定义全局变量,它算是一种短变量声明语句,一般用在局部作用域

常量用const定义,如 const PI = 3.14159

作为Java转Go选手,感觉这里的变量声明方式非常反人类

三、数据类型

  1. 基本类型

    1. 整数类型

      • 有符号:int8、int16、int32、int64、int(根据操作系统位数决定)
      • 无符号:uint8...
    2. 浮点数据类型 float32、float64

    3. 复数类型

    4. 布尔类型

    5. 字符串类型

  2. 复合类型

    • 数组:[n]T 固定长度的相同类型的元素集合
    • 切片:[]T 动态长度的同类型元素视图
    • 哈希容器:map[K]V
    • 结构体:struct{}
  3. 接口类型

    • 定义方法集的抽象类型,比如interface{}
    • 空接口表示任意类型
  4. 引用类型

    • 指针
    • 切片
    • 哈希容器
    • 通道

对于数据类型有一个很重要的点,如果你是Java转的选手,你可能认为基本数据类型值传递,复杂数据类型引用传递,但事实不是这样的。上面提到的几个就是引用类型,其他是进行值传递的,你可以参考一下的代码

package main

import "fmt"

func foo(a int) {
	a += 1
}

func foo1(a *int) {
	*a += 1
}

func foo2(m map[string]int) {
	m["a"] += 1
}

func foo3(s []int) {
	s[0] += 1
}

func foo4(s [1]int) {
	s[0] += 1
}

func main() {
	a := 1
	foo(a)
	fmt.Println(a) // 1

	b := 1
	foo1(&b)
	fmt.Println(b) // 2

	m := map[string]int{"a": 1}
	foo2(m)
	fmt.Println(m["a"]) // 2

	s := []int{1}
	foo3(s)
	fmt.Println(s[0]) // 2

	arr := [1]int{1}
	foo4(arr)
	fmt.Println(arr[0]) // 1
}

这里会有一个很反直觉的点,数组是值传递,但是切片不是,这里是因为切片底层是一个结构体,包含了长度、数组指针、容量,这里作为参数传递的时候在go语言中都是进行了一次拷贝,这里拷贝了指针因此指向了同一块内存区域

四、函数

func foo(a int) b int {
    return a + 1
}

这是一个基本的函数定义,go这里还有一个特性就是函数允许多返回值

func a(a int) (string, error) {
}

五、条件控制

go 中并没有while这种方式,仅仅只能用for实现循环,以下是几种for实现循环的方式

for {
} // 等同while

for i := 0; i <= 3; i++ {
} // for 循环和其他语言别无差异,三个部分都允许为空

go 的 if-else 也和市面上的编程语言基本一致,不过这里对括号的位置有严格要求

if i == 3 {
} else {
}

题外话:我个人之前是学过一点点go语法的,主要看了下go的官方文档,然后这次速通看了B站刘丹冰老师的课