Go第五课-基本数据类型

92 阅读3分钟

类型

image.png

  1. 类型转化。与其他主要编程语⾔言的差异

    1. Go 语言不允许隐式类型转换
    2. 别名和原有类型也不能进⾏隐式类型转换
    type MyInt int64
    
    func TestType(t *testing.T) {
    	var a int = 1
    	var b int64 = 2
    	b = int64(a)
    	var c MyInt
    	c = MyInt(b)
    	t.Log(a, b, c) // 1 1 1
    }
    
  2. 类型的预定义值

    1. math.MaxInt64: 9223372036854775807
    2. math.MaxFloat64: 1.7976931348623157e+308
    3. math.MaxUint32: 4294967295

指针类型,与其他主要编程语⾔言的差异

  1. 不支持指针运算
func TestPoint(t *testing.T) {
	a := 1
	aPtr := &a
	t.Logf("%T %T", a, aPtr) // int *int
	t.Log(a, aPtr)           // 1 0xc0000a40d0
}

func TestPoint(t *testing.T) {
	a := 1
	aPtr := &a
	aPtr = aPtr + 1
	t.Log(a, aPtr) // cannot convert 1 (untyped int constant) to *int
}
  1. string 是值类型,其默认的初始化值为空字符串,⽽不是 nil
func TestPoint(t *testing.T) {
	var s string
	t.Log(s == "") // true
}

整型

  1. 整型溢出问题最容易发生在循环语句的结束条件判断中,因为这也是经常使用整型变量的地方。无论无符号整型,还是有符号整型都存在溢出的问题,所以我们要十分小心地选择参与循环语句结束判断的整型变量类型,以及与之比较的边界值。
  2. 我们可以通过 type 关键字基于原生数值类型来声明一个新类型。通过 Go 提供的类型别名(Type Alias)语法来自定义数值类型。

字符串类型

  1. string 类型其实是一个“描述符”,它本身并不真正存储字符串数据,而仅是由一个指向底层存储的指针和字符串的长度字段组成的。因为字符串类型中包含了字符串长度信息,当我们用 len 函数获取字符串长度时,len 函数只要简单地将这个信息提取出来就可以了。

  2. Go 原生支持 string 的优点:

    1. string 类型的数据是不可变的,提高了字符串的并发安全性和存储利用率。
    2. 没有结尾’\0’,而且获取长度的时间复杂度是常数时间,消除了获取字符串长度的开销。
    3. 原生支持“所见即所得”的原始字符串,大大降低构造多行字符串时的心智负担。
    4. 对非 ASCII 字符提供原生支持,消除了源码在不同环境下显示乱码的可能。Unicode 字符是以 UTF-8 编码格式存储在内存当中的。
  3. 直接将 string 类型通过函数 / 方法参数传入也不会带来太多的开销。

  4. Go 字符串类型的常见操作

    1. for 迭代与 for range 迭代两种形式的迭代对字符串进行操作得到的结果是不同的
    2. for 迭代对字符串进行的操作是一种字节视角的迭代
    3. for range 迭代,我们每轮迭代得到的是字符串中 Unicode 字符的码点值,以及该字符在字符串中的偏移值。
    4. Go 采用字典序的比较策略,分别从每个字符串的起始处,开始逐个字节地对两个字符串类型变量进行比较
  5. 与其他主要编程语⾔的差异

    1. string 是数据类型,不是引⽤或指针类型
    2. string 是只读的 byte slice,len 函数可以它所包含的 byte 数
    3. string 的 byte 数组可以存放任何数据
  6. Unicode VS UTF8

    1. Unicode 是⼀种字符集(code point)
    2. UTF8 是 unicode 的存储实现 (转换为字节序列的规则)
    func TestString(t *testing.T) {
    	s := "\xE4\xB8\xAD"
    	t.Log(s, len(s)) // 中 3
    	s = "中"
    	t.Logf("中 UTF-8 %x", s) // 中 UTF-8 e4b8ad
    	t.Log(s, len(s))        // 中 3 (是byte数)
    	c := []rune(s)
    	t.Log(c, len(c))             // [20013] 1
    	t.Logf("中 unicode %x", c[0]) //中 unicode 4e2d
    }
    
  7. 遍历

    func TestStringFunc(t *testing.T) {
    	s := "A,B,C"
    	parts := strings.Split(s, ",")
    	for _, part := range parts {
    		t.Log(part)
    	}
    	s1 := strings.Join(parts, "-")
    	t.Log(s1) // A-B-C
    }
    
  8. 转化

    func TestStringConvert(t *testing.T) {
    	i := strconv.Itoa(10)
    	t.Logf("type: %T", i) // type: string
    	s := "10"
    	if v, err := strconv.Atoi(s); err == nil {
    		t.Log(10 + v) // 20
    	}
    }