Skip to content

类型

go
bool

string

int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr

byte // uint8 的别名

rune // int32 的别名
     // 表示一个 Unicode 码位

float32 float64

complex64 complex128

零值 (默认值)

数值类型为 0,
布尔类型为 false,
字符串为 ""(空字符串)。

类型转换

go
var i int = 42
var f float64 = float64(i)
var u uint = uint(f)

T(v) 将值 v 转换为类型 T

interface

interface 本身不是值,interface 是“值的包装”

笔记1

go
var i interface{} = "hello"

i 不是 hello ,而是:

go
// 一个 string 类型、值为 hello 的 interface
i = (string, "hello")

go interface 的本质为:

interface value = (dynamic type, dynamic value)

笔记2

interface{} ,没有任何方法约束的接口,任何类型都实现了它

Type Assertion/断言

go
package main

import "fmt"

func main() {
	var i interface{} = "hello"

     // 单返回值(可能 panic)
     // “我确信 i 里装的是 string,否则程序直接崩”
	s := i.(string)
	fmt.Println(s)

     // 双返回值:断言失败,不 panic
	s, ok := i.(string)
	fmt.Println(s, ok)

	f, ok := i.(float64)
	fmt.Println(f, ok)

	ff := i.(float64) // panic: interface conversion: interface {} is string, not float64
	fmt.Println(ff)
}
go
if err, ok := err.(*os.PathError); ok {
	fmt.Println(err.Path)
}
go
var pe *os.PathError
if errors.As(err, &pe) {
	fmt.Println(pe.Path)
}

笔记1

go
s := i.(string)

// 等价于

if i.dynamicType == string {
    return i.value
} else {
    panic
}

类型选择

go
package main

import "fmt"

func do(i interface{}) {
	switch v := i.(type) {
	case int:
		fmt.Printf("二倍的 %v%v\n", v, v*2)
	case string:
		fmt.Printf("%q 长度为 %v 字节\n", v, len(v))
	default:
		fmt.Printf("我不知道类型 %T!\n", v)
	}
}

func main() {
	do(21)
	do("hello")
	do(true)
}