1. 语法
var name type
Go语言的基本类型有:
- bool
- string
- int、int8、int16、int32、int64
- uint、uint8、uint16、uint32、uint64、uintptr
- byte // uint8 的别名
- rune // int32 的别名 代表一个 Unicode 码
- float32、float64
- complex64、complex128
2. 函数
func 函数名(形式参数列表)(返回值列表){
函数体
}
func hypot(x, y float64) float64 {
return math.Sqrt(x*x + y*y)
}
func typedTwoValues() (int, int) { return 1, 2 }
代码管理对比
- Go语言中通过包来管理代码
- Go语言没有.h文件的概念, 在Go中想使用某一个函数时, 只需要import导入对应的包即可
- Go语言中函数、变量公私有管理
- 通过函数名称首字母大小写实现是否公开函数
- 通过变量名称首字母大小写实现是否公开变量
常量变量对比
- Go语言定义常量和变量格式
- 除了以下标准格式外,Go语言还提供了好几种简单的语法糖
var 变量名称 数据类型 = 值;
const 变量名称 数据类型 = 值;
运算符对比
- 算数运算符和C语言几乎一样
- Go语言中++、--运算符不支持前置
- 错误写法: ++i; --i;
- Go语言中++、--是语句,不是表达式,所以必须独占一行
- 错误写法: a = i++; return i++;
- Go语言中++、--运算符不支持前置
流程控制语句对比
- C语言流程控制中的if、switch、for在Go语言都可以使用
- C语言中的四大跳转语句return、break、continue、goto在Go语言都可以使用
- Go语言除了实现C语言中if、switch、for、return、break、continue、goto的基本功能以外,还对if、switch、for、break、continue进行了增强
- 例如: if 条件表达式前面可以添加初始化表达式
- 例如: break、continue可以指定标签
- 例如: switch语句可以当做if/elseif来使用
- ... ...
- 值得注意的是Go语言中没有while循环和dowhile循环, 因为它们能做的Go语言中的for循环都可以做
返回值类型 函数名称(形参列表) { 函数体相关语句; return 返回值; }
func 函数名称(形参列表)(返回值列表) { 函数体相关语句; return 返回值; }
- C语言中没有方法的概念, 但是Go语言中有方法
- 对于初学者而言,可以简单的把方法理解为一种特殊的函数
func (接收者 接受者类型)函数名称(形参列表)(返回值列表) { 函数体相关语句; return 返回值; }
Go语言程序主函数定义格式
- Go语言main函数格式
- func 告诉系统这是一个函数
- main主函数固定名称
- 函数左括号必须和函数名在同一行
- main函数必须在main包中
// 告诉系统当前编写的代码属于哪个包 package main // 定义了一个名称叫做main的函数 func main() { }
C语言关键字和Go语言关键字对比
內建函数 | |||
---|---|---|---|
make | len | cap | new |
append | copy | delete | real |
imag | panic | recover | complex |
标识符
- Go语言的命名规范和C语言一样, 都是采用驼峰命名, 避免采用_命名
- _命名: send_message / say_hello
- 驼峰命名: sendMessage / sayHello
import ( "fmt" "unsafe" ) func main() { fmt.Println("int size = ", unsafe.Sizeof(int(0))) fmt.Println("int8 size = ", unsafe.Sizeof(int8(0))) fmt.Println("int16 size = ", unsafe.Sizeof(int16(0))) fmt.Println("int32 size = ", unsafe.Sizeof(int32(0))) fmt.Println("int64 size = ", unsafe.Sizeof(int64(0))) fmt.Println("uint size = ", unsafe.Sizeof(uint(0))) fmt.Println("uint8 size = ", unsafe.Sizeof(uint8(0))) fmt.Println("uint16 size = ", unsafe.Sizeof(uint16(0))) fmt.Println("uint32 size = ", unsafe.Sizeof(uint32(0))) fmt.Println("uint64 size = ", unsafe.Sizeof(uint64(0))) fmt.Println("uintptr size = ", unsafe.Sizeof(uintptr(0))) fmt.Println("byte size = ", unsafe.Sizeof(byte(0))) fmt.Println("rune size = ", unsafe.Sizeof(rune(0))) fmt.Println("float32 size = ", unsafe.Sizeof(float32(0))) fmt.Println("float64 size = ", unsafe.Sizeof(float64(0))) fmt.Println("true size = ", unsafe.Sizeof(true)) fmt.Println("false size = ", unsafe.Sizeof(false)) }
- Go语言中定义变量有三种格式
// 标准格式 var 变量名称 数据类型 = 值; // 自动推到类型格式 var 变量名称 = 值; // 简短格式(golang官方推荐格式) 变量名称 := 值;
- 一定不要把:=当做赋值运算符来使用
- :=只能用于定义局部变量,不能用于定义全局变量
- 变量组中不能够使用:=
- 通过:=同时定义多个变量, 必须给所有变量初始化
- 通过:=同时定义多个变量, 只要任意一个变量没有定义过,都会做退化赋值操作
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) }
局部变量和全局变量
-
Go语言中局部变量的概念以及全局变量的概念和C语言一模一样
-
局部变量:
- 定义在函数内部的变量以及函数的形参称为局部变量
- 作用域:从定义哪一行开始直到与其所在的代码块结束
- 生命周期:从程序运行到定义哪一行开始分配存储空间到程序离开该变量所在的作用域
-
全局变量:
- 定义在函数外面的变量称为全局变量
- 作用域范围:从定义哪行开始直到文件结尾
- 生命周期:程序一启动就会分配存储空间,直到程序结束
- Go语言中无论是全局变量还是局部变量,只要定义了一个变量都有默认的0值
- int/int8/int16/int32/int64/uint/uint8/uint16/uint32/uint64/byte/rune/uintptr的默认值是0
- float32/float64的默认值是0.0
- bool的默认值是false
- string的默认值是""
- pointer/function/interface/slice/channel/map/error的默认值是nil
- 其它复合类型array/struct默认值是内部数据类型的默认值
var num0 int = 10 var num2 int16 //num2 = num0 // 编译报错, 不同长度的int之间也需要显示转换 num2 = int16(num0)
数值类型和字符串类型之间转换
strconv..FormatXxx()
package main import "fmt" func main() { var num1 int32 = 10 // 第一个参数: 需要被转换的整型,必须是int64类型 // 第二个参数: 转换为几进制, 必须在2到36之间 // 将32位十进制整型变量10转换为字符串,并继续保留10进制格式 str1 := strconv.FormatInt(int64(num1), 10) fmt.Println(str1) // 10 // 将32位十进制整型变量10转换为字符串,并转换为2进制格式 str2 := strconv.FormatInt(int64(num1), 2) fmt.Println(str2) // 1010
var num5 float64 = 3.1234567890123456789 // 第一个参数: 需要转换的实型, 必须是float64类型 // 第二个参数: 转换为什么格式,f小数格式, e指数格式 // 第三个参数: 转换之后保留多少位小数, 传入-1按照指定类型有效位保留 // 第四个参数: 被转换数据的实际位数,float32就传32, float64就传64 // 将float64位实型,按照小数格式并保留默认有效位转换为字符串 str3 := strconv.FormatFloat(num5, 'f', -1, 64) fmt.Println(str3) // 3.1234567 str4 := strconv.FormatFloat(num5, 'f', -1, 64) fmt.Println(str4) // 3.1234567890123457 // 将float64位实型,按照小数格式并保留2位有效位转换为字符串 str5 := strconv.FormatFloat(num5, 'f', 2, 64) fmt.Println(str5) // 3.12 // 将float64位实型,按照指数格式并保留2位有效位转换为字符串 str6 := strconv.FormatFloat(num5, 'e', 2, 64) fmt.Println(str6) // 3.12
strconv.ParseXxx()
var str1 string = "125" // 第一个参数: 需要转换的数据 // 第二个参数: 转换为几进制 // 第三个参数: 转换为多少位整型 // 注意点: ParseInt函数会返回两个值, 一个是转换后的结果, 一个是错误 // 如果被转换的数据转换之后没有超出指定的范围或者不能被转换时, // 那么错误为nil, 否则错误不为nil // 将字符串"125"转换为10进制的int8 num1, err := strconv.ParseInt(str1, 10, 8)
func main() { var num1 int32 = 110 // 快速将整型转换为字符串类型 // 注意:Itoa方法只能接受int类型 var str1 string = strconv.Itoa(int(num1))
func main() { var num1 int32 = 110 // Sprintf函数和Printf函数很像, 只不过不是输出而将格式化的字符串返回给我们 var str1 string = fmt.Sprintf("%d", num1)
const 常量名称 数据类型 = 值const 常量名称 = 值
const num1, num2 int = 100, 200
- Go语言实现枚举格式
const( 枚举元素1 = iota 枚举元素2 = iota ... ... )
package main import "fmt" func main() { const ( male = iota female = iota yao = iota )