泛操作
泛操作
变量
内存中的一个数据存储表示
声明定义、赋值、使用
由于有 默认初始化,这里不区分 声明与定义
main.go
package main
import "fmt"
func main() {
    var age int 				// 变量声明
    age = 18					// 变量赋值
    fmt.Println("age = ", age)	// 变量使用
    
    var age2 int = 18; 			// 变量的声明和赋值可以合在一起
}其他语法糖或特性
main.go
var num1 int = 18	// 声明并赋值
fmt.Println(num1)
var num2 int		// 自动初始化
fmt.Println(num2)
var str1 = "18"    	// 自动类型推导
fmt.Println(str1)
str2 := "hello"		// 省略var,注意不能忽略冒号
fmt.Println(str2)
var n1, n2, n3 int	// 多个变量声明
var n4, n5, n6 = 10, "jack", 7.8
n7, n8 := 10, "duck"全局与局部变量
package main
import(					// 批量声明的语法糖 (引入)
    "fmt"
    "unsafe"
)
var n1 int = 0			// 全局变量
var (					// 批量声明的语法糖 (类型声明)
    n9 = 500
    n10 = "netty"
)
func main() {
    var n2 int = 1		// 局部变量
}个人吐槽:
说好的语言特点是只有一种写法,但写法有的是比其他语言少……而有的语法糖反而比其他语言还多了……。少掉的东西中:
部分是像 编译强制初始化这种是更根本的东西,
但大部分则是一些换行和空格这种仅编码风格的约束。有种设计者强制所有人共用同一个
.clang-format或者eslint,且不符合则不给编译通过,的这种感觉。
符合我平时的写法我会觉得早该这么做了,否则我就感觉设计者闲得蛋疼,加这种约束闲得没事干)
下面是更详细的补充:
自动初始化
复习下:
与其他语言不同:
- 有默认初始化
 
- Java / Kotlin / Python / Swift / Go
 
- 基本类型:默认初始化为零值
 - 对象引用:默认初始化为空 (java为null,kotlin为null,python为None,swift为nil,go为nil)
 - TypeScript/JavaScript:
 
- 默认初始化为 undefined
 - 强制初始化
 
- Rust
 
- 强制初始化,否则报错,不存在默认初始化的行为
 - 无默认初始化
 
- C/C++(这一类就只有C/C++了,hhhh)
 
- 基本类型:无默认初始化,成员变量也是。使用这些变量是未定义行为,且无物理内存及虚拟内存对应的值是随机的
 - 全局变量/静态变量:默认初始化为零值
 
Go的默认值:
| 数据类型 | 默认值 | 
|---|---|
| 整数类型 | 0 | 
| 浮点类型 | 0.0 | 
| 布尔类型 | false | 
| 字符串类型 | "" | 
自动类型推导
与其他语言不同:
更类似于typescript语言,像C++是需要用auto关键字的
初始化检查
var n1 int8 = 2.3			// 编译错误,类型不符
var n2 int8 = int12 + 128	// 编译错误,超出界限省略var写法 (:= 写法)
批量声明写法
类型转换
Go只有强制转换,没有隐式转换,哪怕小类型转大类型。
语法上 T(v) 就可以了,和其他语言类似,也会出现类型缩窄
数字类型转化
var n1 int = 100
var n2 float32 = n1				// 报错
var n2 float32 = float32(n1)	// 正确
var n5 int32 = 12
var n6 int64 = n5 + 30			// 报错
var n6 int64 = int64(n5) + 30	// 正确数值与string 互相转化
(字符串转化相关,详见 “模块库/字符串库”)
类/接口的互转
派生类转基类不需要额外转换,里氏替换原则。基类转派生类则需要类型转换。
同理,类转接口类型不需要额外转换,反过来则需要使用类型断言:
// 通用语法
// value:变量的值
// ok:book类型
// element:interface变量
// T:断言类型
value, ok = element.(T)
// 举例。将人转中国人
chinese, flag = person.(Chinese)类型/占用内存打印
package main
import "fmt"
import "unsafe"
func main(){
    var num3 = 28
    fmt.Printf("num3的类型是 %T", num3)   // int
    fmt.Println(unsafe.Sizeof(num3))	// 8 (Byte)
}运算符
与其他语言不同:
- Go的整除是向零而非向下取整
 - 极大限制了C/C++/Java的++/--骚操作,只能单独一个表达式使用,且只能放在变量后面
(个人吐槽:对于学生来说好耶,但老程序员感觉这不是很爽) 
几乎和其他语言一样,这里没有三目运算符
// 1. 算数运算符
+, -, *, /, %, ++, --	// 相同点:整数除法也是整除,也有逻辑运算符也有短路
// 2. 赋值运算符
=, +=, -=, *=, /=, %=
// 3. 关系运算符
==, !=, <, >, <=, >=
// 4. 逻辑运算符
&&, ||, !
// 5. 位运算符
&, |, ^
// 6. 其他运算符
&, *优先级:(越靠前越优先,反正我也懒得记,不常用不记得的就加括号)
| 分类 | 运算符 | 结合性 | 
|---|---|---|
| 后缀运算符 (伪单目) | ()、[]、-> | 从左到右 | 
| 单目运算符 | 从右到左 | |
| 算数运算符 (乘除取余 > 加减) | 从左到右 | |
| 位移运算符 | 从左到右 | |
| 关系运算符 | 从左到右 | |
| 相等/不相等 | 从左到右 | |
| 按位运算 (与 > 异或 > 或) | 从左到右 | |
| 逻辑运算符 (与 > 或,非归类到单目) | 从左到右 | |
| 赋值运算符 | 从右到左 | |
| 逗号运算符 | 从左到右 | 
链接到当前文件 0
没有文件链接到当前文件