类型
最基础的部分就是类型。其中包含有最基础的基础类型,以及一些其他非基础类型。
为什么需要深刻的了解类型。因为不同的类型的属性,决定着类型所能够操作的范围、以及所具备基本操作方法。这些是再往上构建更多东西的基本需求。
其中包含有以下几个常规变量:
* bool类型
* 数字类型: 有符号整型、无符号整型、浮点型
* 字符串类型
* 常量
后续将会从类型属性、类型操作方法两个部分来分别介绍各个类型。而针对其他类型不同的类型如:map,数组,slices,struct等类型,将独立进行介绍。
bool
bool类型表示一个布尔值,值为true或者false。
package main
import "fmt"
func main() {
// 声明初始化
a := true
b := false
var d bool
d = false
// bool操作
fmt.Println("a:", a, "b:", b)
c := a && b //与操作
fmt.Println("c:", c)
d := a || b //或操作
fmt.Println("d:", d)
}
输出:
a: true b: false
c: false
d: true
解析:
c 赋值为 a && b。仅当 a 和 b 都为 true 时,操作符 && 才返回 true。因此,在这里 c 为 false。
当 a 或者 b 为 true 时,操作符 || 返回 true。在这里,由于 a 为 true,因此 d 也为 true。
数字类型
不同的整型类型,所能够表示的最大数字范围不一样。所以我们再使用的时候,需要考虑到具体的使用范围,选择对应的数字类型。
如下会区分出不同类型的具体定义方法,比特位数,最终固定取值范围。
有符号整型
int8:表示 8 位有符号整型
大小:8 位
范围:-128~127
int16:表示 16 位有符号整型
大小:16 位
范围:-32768~32767
int32:表示 32 位有符号整型
大小:32 位
范围:-2147483648~2147483647
int64:表示 64 位有符号整型
大小:64 位
范围:-9223372036854775808~9223372036854775807
int:根据不同的底层平台(Underlying Platform),表示 32 或 64 位整型。除非对整型的大小有特定的需求,否则你通常应该使用 int 表示整型。
大小:在 32 位系统下是 32 位,而在 64 位系统下是 64 位。
范围:在 32 位系统下是 -2147483648~2147483647,而在 64 位系统是 -9223372036854775808~9223372036854775807。
package main
import "fmt"
func main() {
var a int = 89
b := 95
fmt.Println("value of a is", a, "and b is", b)
}
上面程序会输出 value of a is 89 and b is 95。
在上述程序中,a 是 int 类型,而 b 的类型通过赋值(95)推断得出。上面我们提到,int 类型的大小在 32 位系统下是 32 位,而在 64 位系统下是 64 位。接下来我们会证实这种说法。
在 Printf 方法中,使用 %T 格式说明符(Format Specifier),可以打印出变量的类型。Go 的 unsafe包提供了一个 Sizeof 函数,该函数接收变量并返回它的字节大小。unsafe 包应该小心使用,因为使用 unsafe 包可能会带来可移植性问题。
package main
import (
"fmt"
"unsafe"
)
func main() {
var a int = 89
b := 95
fmt.Println("value of a is", a, "and b is", b)
fmt.Printf("type of a is %T, size of a is %d", a, unsafe.Sizeof(a)) // a 的类型和大小
fmt.Printf("\ntype of b is %T, size of b is %d", b, unsafe.Sizeof(b)) // b 的类型和大小
}
无符号整型
uint8:表示 8 位无符号整型
大小:8 位
范围:0~255
uint16:表示 16 位无符号整型
大小:16 位
范围:0~65535
uint32:表示 32 位无符号整型
大小:32 位
范围:0~4294967295
uint64:表示 64 位无符号整型
大小:64 位
范围:0~18446744073709551615
uint:根据不同的底层平台,表示 32 或 64 位无符号整型。
大小:在 32 位系统下是 32 位,而在 64 位系统下是 64 位。
范围:在 32 位系统下是 0~4294967295,而在 64 位系统是 0~18446744073709551615。
浮点型
float32:32 位浮点数
float64:64 位浮点数
下面一个简单程序演示了整型和浮点型的运用。
package main
import (
"fmt"
)
func main() {
a, b := 5.67, 8.97
fmt.Printf("type of a %T b %T\n", a, b)
sum := a + b
diff := a - b
fmt.Println("sum", sum, "diff", diff)
no1, no2 := 56, 89
fmt.Println("sum", no1+no2, "diff", no1-no2)
}
a 和 b 的类型根据赋值推断得出。在这里,a 和 b 的类型为 float64(float64 是浮点数的默认类型)。我们把 a 和 b 的和赋值给变量 sum,把 b 和 a 的差赋值给 diff,接下来打印 sum 和 diff。no1 和 no2 也进行了相同的计算。上述程序将会输出:
type of a float64 b float64
sum 14.64 diff -3.3000000000000007
sum 145 diff -33
其他数字类型
byte 是 uint8 的别名。
rune 是 int32 的别名。
数字类型的操作
针对数字类型常用的操作就是进行数学运算。而具体能够进行哪些数字运算操作。
----------------------
A值为:10 B值为:20
+ 相加 A + B 输出结果 30
- 相减 A - B 输出结果 -10
* 相乘 A * B 输出结果 200
/ 相除 B / A 输出结果 2
% 求余 B % A 输出结果 0
++ 自增 A++ 输出结果 11
-- 自减 A-- 输出结果 9
----------------------
package main
import "fmt"
func main() {
a := 100
b := 20
fmt.Println(a, b)
result := a + b
fmt.Printf("加法运算结果: %d\n", result)
result = a - b
fmt.Printf("减法运算结果: %d\n", result)
result = a * b
fmt.Printf("乘法运算结果: %d\n", result)
result = a / b
fmt.Printf("除法运算结果: %d\n", result)
result = a % b
fmt.Printf("取余运算结果: %d\n", result)
a++
fmt.Printf("a自增运算结果: %d\n", a)
b--
fmt.Printf("b自减运算结果: %d\n", b)
}
关系运算符
----------------------
== 检查两个值是否相等,如果相等返回 True 否则返回 False。 (A == B) 为 False
!= 检查两个值是否不相等,如果不相等返回 True 否则返回 False。 (A != B) 为 True
> 检查左边值是否大于右边值,如果是返回 True 否则返回 False。 (A > B) 为 False
< 检查左边值是否小于右边值,如果是返回 True 否则返回 False。 (A < B) 为 True
>= 检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。 (A >= B) 为 False
<= 检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。 (A <= B) 为 True
----------------------
string 类型
在 Golang 中,字符串是字节的集合。如果你现在还不理解这个定义,也没有关系。我们可以暂且认为一个字符串就是由很多字符组成的。我们后面会在一个教程中深入学习字符串。 下面编写一个使用字符串的程序。
package main
import (
"fmt"
)
func main() {
first := "Naveen"
last := "Ramanathan"
name := first +" "+ last
fmt.Println("My name is",name)
}
上面程序中,first 赋值为字符串 "Naveen",last 赋值为字符串 "Ramanathan"。+ 操作符可以用于拼接字符串。我们拼接了 first、空格和 last,并将其赋值给 name。上述程序将打印输出 My name is Naveen Ramanathan。
string类型的操作
单独的章节说明字符串类型的差异。
类型转换
错误的示例,需要同时对两个不同类型做操作的时候。需要先进行类型的转换。golang当中是没办法对不同类型做同一操作的。例如数学运算。另外对不同类型进行赋值的时候,也同样会出现错误。在golang当中是需要再编译的时候就已经明确好具体的类型。并且类型是正确。golang是强类型特征的,必须一致。
类型转换的语法:type(v)。把 v 转换为 T 类型的语法是 T(v)。
package main
import (
"fmt"
)
func main() {
i := 55 //int
j := 67.8 //float64
sum := i + j //不允许 int + float64 这里对不同类型进行同一操作,会出现类型错误。
fmt.Println(sum)
}
i和 j 应该是相同的类型。在这里,我们把 j 转换为 int 类型。把 v 转换为 T 类型的语法是 T(v)。
package main
import (
"fmt"
)
func main() {
i := 55 //int
j := 67.8 //float64
sum := i + int(j) //j is converted to int
fmt.Println(sum)
}
赋值时的类型转换
package main
import (
"fmt"
)
func main() {
i := 10
var j float64 = float64(i) // 若没有显式转换,该语句会报错
fmt.Println("j", j)
}
常量
术语常量在Go语言中表示固定的值,例如5, -89, “I love Go”,67.89等等。固定值,已经定义出来的固定值是不能再被用来修改值的。
这种类型的变量。常用来设定一些系统需要的固定值。并且常量是无类型的,只有当需要类型的时候,才会获取具体常量的默认类型。
常量不可重复赋值
如下重复赋值会出现错误。
package main
func main() {
const a = 55 // 允许
a = 89 // 不允许重新赋值
}
常量的值会在编译的时候确定。因为函数调用发生在运行时,所以不能将函数的返回值赋值给常量。
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("Hello, playground")
var a = math.Sqrt(4) // 允许
const b = math.Sqrt(4) // 不允许
}
在上面的程序中,因为 a 是变量,因此我们可以将函数 math.Sqrt(4) 的返回值赋值给它(我们将在单独的地方详细讨论函数)。
b 是一个常量,它的值需要在编译的时候就确定。函数 math.Sqrt(4) 只会在运行的时候计算,因此 const b = math.Sqrt(4) 将会抛出错误 error main.go:11: const initializer math.Sqrt(4) is not a constant)
字符串常量
字符串常量:常量是指定某些具体的值,而非变量。但当一个变量被赋值为一个常量值的时候,它就变成一个常量变量。
例如: "this is const string" 这个是一个常量值。而const s = "this is const stirng" s就是一个常量变量。一样是不能被重复赋值的。指针是指定到了某个常量空间的。
双引号中的任何值都是 Go 中的字符串常量。例如像 Hello World 或 Sam 等字符串在 Go 中都是常量。什么类型的字符串属于常量?答案是他们是无类型的。
答案是无类型的常量有一个与它们相关联的默认类型,并且当且仅当一行代码需要时才提供它。在声明中 var name = "Sam" , name 需要一个类型,它从字符串常量 Sam 的默认类型中获取。
package main
import (
"fmt"
)
func main() {
var name = "Sam" //此处name就是一个无类型的字符串常量。
fmt.Printf("type %T value %v", name, name)
}
Go 是一个强类型的语言,在分配过程中混合类型是不允许的。让我们通过以下程序看看这句话是什么意思。
无类型的常量有一个与它们相关联的默认类型,并且当且仅当一行代码需要时才提供它。在声明中 var name = "Sam" , name 需要一个类型,它从字符串常量 Sam 的默认类型中获取。
package main
func main() {
var defaultName = "Sam" // 允许。 defaultName被定义为一个无类型的
type myString string
var customName myString = "Sam" // 允许。
var name1 string = "this is my name" //被明确的定义为一个
customName = defaultName // 不允许
name1 = defaultName //允许。 因为在需要比对name1 和 defaultName的时候。defaultName的默认类型是string类型。不属于混合类型。
}
布尔常量
布尔常量和字符串常量没有什么不同。他们是两个无类型的常量 true 和 false。字符串常量的规则适用于布尔常量,所以在这里我们不再重复。以下是解释布尔常量的简单程序。
package main
func main() {
const trueConst = true
type myBool bool
var defaultBool = trueConst // 允许
var customBool myBool = trueConst // 允许
defaultBool = customBool // 不允许
}
数字常量
数字常量包含整数、浮点数和复数的常量。数字常量中有一些微妙之处。数字都是常量,而数字常量的默认类型是什么。这和具体的变量写法有关系。例如 var a = 5.5 那就是浮点型。var a = 5就会是一个整型。
package main
import (
"fmt"
)
func main() {
var i = 5
var f = 5.6
var c = 5 + 6i
fmt.Printf("i's type %T, f's type %T, c's type %T", i, f, c)
}
在上面的程序中,每个变量的类型由数字常量的语法决定。5 在语法中是整数, 5.6 是浮点数,5+6i 的语法是复数。当我们运行上面的程序,它会打印出 i's type int, f's type float64, c's type complex128。
数字表达式
数字常量可以在表达式中自由混合和匹配,只有当它们被分配给变量或者在需要类型的代码中的任何地方使用时,才需要类型。
package main
import (
"fmt"
)
func main() {
var a = 5.9/8
fmt.Printf("a's type %T value %v",a, a)
}
在上面的程序中, 5.9 在语法中是浮点型,8 是整型,5.9/8 是允许的,因为两个都是数字常量。除法的结果是 0.7375 是一个浮点型,所以 a 的类型是浮点型。这个程序的输出结果是: a's type float64 value 0.7375。
小结:
* 语言最基础部分就是变量,变量中包含了几个常规类型。
* bool布尔类型: 定义var s bool = true。 同时能够进行与或操作 && ||
* 数字类型: 数字类型因数字表示范围。定义了多种整型类型如int8 uint8 int(32,64位操作系统的范围由系统所决定。并且能够进行数学运算,以及关系运算。
* 类型转换: golang是强类型,不支持混合类型的操作。当需要进行不同类型的同一操作是,需要先进行类型转换。转换的语法是 type(value) T(i) T是类型值,i是具体转换值。如 int(5.5)
* 字符创类型: 将单独的章节说明。
* 常量: 常量是指固定值。而const常量变量是不能够被重复赋值的。如3,'string'都是常量。一个变量赋值常量时是无类型的。只有在需要判断类型时,才会取常量的默认类型。
* 表达式:在一个表达式中混油常量。然后表达式又赋值给其他变量。这个变量也会是无类型。只有当需要执行时,才会判断类型。
参考链接:
https://blog.csdn.net/cbmljs/article/details/83578381