基本数据类型之数字、bool、string、byte、rune、复数

 

 

一、数据类型


golang中的数据类型可以分为基础数据类型和派生数据类型

二、整型


整数又区分不同长度、有无符号。不同的类型的整数占用的空间大小以及取值范围不同

定义

package main

import "fmt"

func main() {
    var v = 1024       // 自动推导默认为int类型
    var a int8 = 24
    var b uint8 = 223
    var c int16 = 32700
    var d uint16 = 64455
    var e int64 = 120000
    var f uint64 = 220000
    fmt.Println(a, b, c, d, e, f)
}

要点

自动推导整数的类型是int

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    var v = 1024
    fmt.Printf("变量的类型为:%T, 大小为:%d字节\n", v, unsafe.Sizeof(v))   // 变量的类型为:int 大小为:8字节
}
View Code

注意整数类型的取值范围,比如不能把一个129整数赋值给int8类型

package main

import "fmt"

func main() {
    var a int8 = 129
    fmt.Println(a)  // constant 129 overflows int8
}
View Code

即使值一样,但是类型不一样,也是看成不同的类型, 例如int8类型的5与uint8类型的5就是不同的类型

package main

import "fmt"

func main() {
    var a uint8 = 12 
    var b int8 = 12
    fmt.Printf("变量a的类型为%T\n", a)  // uint8
    fmt.Printf("变量b的类型为%T\n", b) // int8
}
View Code

对于类型转换,低位转高位正常,反之异常

package main

import "fmt"

func main() {
    var a int16 = 13146
    b := int(a)       // 正常,低位转高位,输出13146
    c := int8(a)      // 依次,高位转低位,输出90
    fmt.Println(b, c) // 输出13146 90
}
View Code

不同的类型是不能运算的,即使它们的值一样,可以转成相同的类型然后运算,要注意转换的长度

package main

import "fmt"

func main() {
    var a int8 = 10
    var b int16 = 10

    // int8不能和int16相加
    fmt.Println(a + b) // a + b (mismatched types int8 and int16)
    // 可以将a转换成16然后在进行计算
    fmt.Println(int16(a) + b) // 输出20
}
View Code

满足要求的情况下尽可能采用占用空间小的数据类型,比如年龄,范围应该在0-255之间,采用byte或uint8就够了,而没必要使用int64

三、浮点类型


浮点类型只有float32(单精度)、float64(双精度)两种, 其类型零值是0.0. 推荐使用float64, 因为精度比较高
使用类型推导得到的也是float64。 浮点类型都是有符号的

package main

import "fmt"

func main() {
    //1. 定义float32、float64类型
    var a float32 = 12345.12
    var b float64 = 12345.12
    fmt.Println(a, b)

   // 2. 类型推导得到也是float64
   c := 3.125
   fmt.Printf("%T", c) // 输出float64

   // 3. 比较float32和float64精度
   var e float32 = 11.1234565 // 小数位超过6位,四舍五入,精度丢失
   var f float64 = 11.1234565 
   fmt.Println(e, f)          // 输出 11.123457 11.1234565

使用浮点数需要考虑精度的问题,尤其是转换的时候,建议使用float64类型,因为精度高

四、byte


byte用来表示单个ascii字符,它是unit8(0~255)的别名, 实际上byte就是个整数。 打印字符时得到的是它的Unicode码值,字符用单引号表示

package main

import "fmt"

func main() {
    // 定义byte
    var a byte = 'h'

    // 1. 查看a的类型,得出是uint8,实际上byte是unit8的别名
    fmt.Printf("%T\n", a) // 输出 uint8

    // 2. 打印变量a,得到是字符'h'的unicode码值(整数)
    fmt.Println(a) // 输出 104

    // 3. 如果想打印出字符,可以格式化
    fmt.Printf("%c", a) // 输出 h
}

当用byte表示一个汉字时会报错,因为byte是1个字节,而一个汉字通常占用2~4字节,所以byte不能存储一个汉字字符,可以使用rune类型

package main

import "fmt"

func main() {
    var a byte = ''   // 这样不行, 溢出了, 因为byte实际上unit8,取值范围只能是0-255
    fmt.Println(a)      // 字符本质上就是数字
    fmt.Printf("%T", a) // 输出byte类型 
}

五、rune


rune是int32 (0~4294967296)的别名,表示字符的unicode码值,相比byte能表示更多的字符

package main
import "fmt"
func main() {
   // 定义个rune类型
    var s rune = ''
    v := ''               // 使用类型推导
    fmt.Println(s)        // 输出: 20320   表示字符s的Unicode码值
    fmt.Printf("%T\n", s) // 输出: int32   s实际上是int32类型
    fmt.Printf("%T\n", v) // 输出: int32   v实际上是int32类型
}

既然byte、rune是整数,它们就可以进行计算

package main

import "fmt"

func main() {
    var a byte = 'a'
    var b rune = ''

    fmt.Println(a + 100) // 输出: 197
    fmt.Println(b + 200) // 输出: 20520
}
View Code

小结:字符本质就是个整数, byte用来表示ascii字符,而rune可以表示所有的字符。

六、string


go的字符串是由一串字符组成的序列,其底层是字节数组。 字符串是不可变的,不能修改

常用操作: 字符串长度、字符串遍历、拼接、子序列、string包使用

1. 定义字符串

字符串定义可以通过(" ")双引号和(``)反引号两方式, 区别在于前者会识别转义字符,后者不会

使用双引号

package main

import "fmt"

func main() {

    var a string = "hello\nword"  // 会识别里面的\n
    b := "你好中国"

    // 查看类型
    fmt.Printf("%T\n", a) // 输出string
    fmt.Printf("%T\n", b) // 输出string
}
View Code

使用反引号

package main

import "fmt"

func main() {
    a := `abc\n\tabc`   // 使用反引号
    b := `
        你好中国\n
        helloword"\t
        `
    fmt.Println(a)    // 不识别转义字符
    fmt.Println(b)    // 不识别转义字符
}
View Code

2. 字符串不能修改

package main
import "fmt"

func main() {
    a := "hello"
    a[0] = "H"    // 错误 cannot assign to a[0]   提示不能修改
    fmt.Println(a)
}

3. 通过len函数查看长度

注意一个汉字占用三个字符,字母和数字为一个字符

package main
import "fmt"
func main() {
    a := "abcde"
    b := "你好中国"
    fmt.Println(len(a))  // 输出5
    fmt.Println(len(b))  // 输出12,因为一个汉字占三个字节
}

4. 获取字符串子序列

如果是打印单个字符得到的是Unicode码值, 可以通过fmt.Printf格式化得到原值

package main 

import "fmt"

func main() {
    s := "hello word"
    // 获取子序列,得到的字符的Unicode的码值
    fmt.Println(s[0], s[1]) // 输出: 104 101  //这也说了字符串是由字节拼接

    // 可以格式化输出得到字母
    fmt.Printf("%c %c\n", s[0], s[1])   // 输出: h e
    fmt.Println(s[1:4])                 // 输出: ell
    fmt.Println(s[2:])                  // 输出: llo word
}

5. 字符串拼接

字符串拼接可以通过 + 和 string.join方式

package main

import "fmt"

func main() {

    // 通过 + 号
    a := "hello" + "word"
    fmt.Println(a)

    // 如果要拼接的一行很多,可以分行,但是是+号必须放在后面
    b := "hello a" + "hello b" + "hello c" +
        "hello d" + "hello e" + "hello f" +
        "hello g"
    fmt.Println(b) // hello ahello bhello chello dhello ehello fhello g
}
View Code

7.string包使用

参考

七. 复数


复数是由两个实数(在计算机中浮点数表示) 构成,一个表示实部(real), 一个表示虚部(image),有两complex64、complex128(默认)两种类型

package main

import "fmt"

func main() {
    // 定义一个complex64类型的复数
    var t complex64
    t = 2.1 + 3.14i
    fmt.Println(t) // 输出 (2.1+3.14i)

    // 自动推导类型, 默认为complex128
    v := 3.3 + 4.4i
    fmt.Println(v)        // 输出 (3.3+4.4i)
    fmt.Printf("%T\n", v) // 输出 complex128

    // 通过内置的real、image函数获取实部、虚部
    fmt.Println(real(v), imag(v)) // 输出 3.3 3.4
}

八. bool


非真及假, bool类型的值只有true(真)和false(假), 其大小为1字节,零值为false

package main

import "fmt"

func main()  {

    // 1. 声明一个bool类型
    var a bool     // 未初始化, 所以为零值,默认是false
    fmt.Println(a) // 输出false
    a = true       // 重复赋值(初始化)
    fmt.Println(a) // 输出true

    // 2. 类型推导
    var b = true
    var c = false
    fmt.Println(b, c) // 输出true false

    // 3. 短变量
    d := true
    fmt.Println(d)   // 输出true

    // 4. 通过表达式
    e := (1 == 2)
    fmt.Println(e)   // 输出false
    // 查看类型
    fmt.Printf("%T", e)  // 输出bool
}
View Code

 

posted @ 2019-08-11 17:00  opss  阅读(1127)  评论(0)    收藏  举报