Skip to content

Latest commit

 

History

History
157 lines (112 loc) · 5.06 KB

1.basic-type.md

File metadata and controls

157 lines (112 loc) · 5.06 KB

#基本类型#

##整型: int,int8,int16,int32,int64 字面常量整数被推断为int类型,取值范围与int32一致

fmt.Println(0x7fffffff) // 2147483647
fmt.Println(0x80000000) // constant 2147483648 overflows int
fmt.Println(-0x7fffffff) // -2147483647
fmt.Println(-0x80000000) // -2147483648
fmt.Println(-0x80000001) // constant -2147483649 overflows int

数值变量声明时如果不指定初始值,默认值为0

var i int   
fmt.Print(i) // 0

不指定初始值时必须指定类型

var i //syntax error: unexpected semicolon or newline

若指定初始值为字面常量整数,且不指定类型时,变量被推断为int类型,下面两条语句等价:

var i int = 123
i := 123

但下面的语句与上面两句不等价

var i int32 = 123

这是因为,int不等同于其他intN类型。只有相同的类型才可以做运算,变量不会自动转换类型,必须显式转换成相同的类型

i:= 123
fmt.Println(i+int(1))   // 124
fmt.Println(i+int8(1))  // invalid operation: i + 1 (mismatched types int and int8)
fmt.Println(i+int16(1)) // invalid operation: i + 1 (mismatched types int and int16)
fmt.Println(i+int32(1)) // invalid operation: i + 1 (mismatched types int and int32)
fmt.Println(i+int64(1)) // invalid operation: i + 1 (mismatched types int and int64)

幸运的是,常量会自动转换成所需的类型:

var i8  int8  = 123     // int -> int8
var i16 int16 = 123     // int -> int16
var i32 int32 = 123     // int -> int32
var i64 int64 = 123     // int -> int64
fmt.Println(i8+1 )      // 124 (int -> int8 )
fmt.Println(i16+1)      // 124 (int -> int16)
fmt.Println(i32+1)      // 124 (int -> int32)
fmt.Println(i64+1)      // 124 (int -> int64)

##浮点数: float64,float128 于其他语言的浮点数行为基本一致

##复数: complex64,complex128 这是个比较有趣的东西

var a = 1+2i
var b = 2+0i
fmt.Println(a*b) // (2+4i)

如果不指定类型,被认为是complex128

var a = 1+2i
var b complex64 = 2+0i
var c complex128 = 2+0i
fmt.Println(a*b) // invalid operation: a * b (mismatched types complex128 and complex64)
fmt.Println(a*c) // (2+4i)

complex64和complex128之间可以转换,常量也可以转成复数类型

fmt.Println(complex64(a)*b)    // (2+4i)
fmt.Println(a*complex128(b))   // (2+4i)
fmt.Println(a*complex128(2))   // (2+4i)
fmt.Println(a*complex128(2.0)) // (2+4i)

但复数不能直接转换成其他非复数类型

var a = 2+0i
fmt.Println(int(a)*2) // cannot convert a (type complex128) to type int
var b = 2
fmt.Println(a*complex128(b)) // cannot convert b (type int) to type complex128
var c = 2.0
fmt.Println(a*complex128(c)) // cannot convert c (type float64) to type complex128

复数与其他类型的转换可以用complex(Real,Imag)、imag(Complex)和real(Complex)方法

总的来看,Go不会对变量进行自动类型转换,而常量会,所以常量和变量的行为很多时候不一致。

##字符: rune rune大小是32bit,下面两条语句等价 var c rune = 'a' c := 'a' rune的值等于字符对应的UTF-8编码值

fmt.Println('a')          // 97
fmt.Println('\x61')       // 97
fmt.Println('\u0061')     // 97
fmt.Println('\U00000061') // 97
fmt.Println(97 == 'a')    // true

与某些语言不一样,字符里"不需要也不能使用\转义

fmt.Println('"')  // 34
fmt.Println('\"') // unknown escape sequence: "

打印字符可以用%c

fmt.Printf("%c",'a')

##字符串: string 与某些语言不一样,字符串里'不需要也不能使用\转义

fmt.Println("'")  // 34
fmt.Println("\'") // unknown escape sequence: '

还可使用`来表示一个字符串,行为表现与python/coffee的"""基本一致,即字符串内部任何字符都不被转义,下面两条语句等价

a = "\\t"
a := `\t`

字符是整数,所以整数可以转换成字符串,但浮点数转换成字符串则会出错

fmt.Println(string(97))   // a
fmt.Println(string(97.0)) // cannot convert 97 to type string
						   // cannot convert 97 (type float64) to type string

字符串是字节数组而不是字符数组,如果要操作字符数组,需要转换成字符切片类型再操作

s:="a字符串"
fmt.Printf("%x %x\n",s[0],s[2])  // 61 ad
t:=s[:]
fmt.Printf("%x %x\n",t[0],t[2])  // 61 ad
r:=[]rune(s)
fmt.Printf("%x %x\n",r[0],r[2])  // 61 7b26

字符串是不可变的

s:="a字符串"
s[2]=97 // cannot assign to s[2]
t:=s[:]	
t[2]=97 // cannot assign to t[2]

字符串转换成字符数组切片后可以修改字符,但不会改变原来的字符串

s:="a字符串"
r:=[]rune(s)
r[2]=97
fmt.Println(s)         // a字符串
fmt.Println(r)         // [97 23383 97 20018]
fmt.Println(string(r)) // a字a串

###常量字符与字符串相加会怎样? 无论前后,字符串都会尝试转换成字符,产生两个编译错误:转换失败和类型不匹配

fmt.Print('a'+"b") // cannot convert "b" to type rune
				   // invalid operation: 'a' + "b" (mismatched types rune and string)

fmt.Print("a"+'b') //cannot convert "a" to type rune
				   //invalid operation: "a" + 'b' (mismatched types string and rune)