Golang package builtin 中内置函数我分为两部分介绍,第一部分为基础类型,第二部分为包含函数、接口,较复杂一些
第一部分// bool is the set of boolean values, true and false. type bool bool // true and false are the two untyped boolean values. const ( true = 0 == 0 // Untyped bool. false = 0 != 0 // Untyped bool. ) // uint8 is the set of all unsigned 8-bit integers. // Range: 0 through 255. type uint8 uint8 // uint16 is the set of all unsigned 16-bit integers. // Range: 0 through 65535. type uint16 uint16 // uint32 is the set of all unsigned 32-bit integers. // Range: 0 through 4294967295. type uint32 uint32 // uint64 is the set of all unsigned 64-bit integers. // Range: 0 through 18446744073709551615. type uint64 uint64 // int8 is the set of all signed 8-bit integers. // Range: -128 through 127. type int8 int8 // int16 is the set of all signed 16-bit integers. // Range: -32768 through 32767. type int16 int16 // int32 is the set of all signed 32-bit integers. // Range: -2147483648 through 2147483647. type int32 int32 // int64 is the set of all signed 64-bit integers. // Range: -9223372036854775808 through 9223372036854775807. type int64 int64 // float32 is the set of all IEEE-754 32-bit floating-point numbers. type float32 float32 // float64 is the set of all IEEE-754 64-bit floating-point numbers. type float64 float64 // complex64 is the set of all complex numbers with float32 real and // imaginary parts. type complex64 complex64 // complex128 is the set of all complex numbers with float64 real and // imaginary parts. type complex128 complex128 // string is the set of all strings of 8-bit bytes, conventionally but not // necessarily representing UTF-8-encoded text. A string may be empty, but // not nil. Values of string type are immutable. type string string // int is a signed integer type that is at least 32 bits in size. It is a // distinct type, however, and not an alias for, say, int32. type int int // uint is an unsigned integer type that is at least 32 bits in size. It is a // distinct type, however, and not an alias for, say, uint32. type uint uint // uintptr is an integer type that is large enough to hold the bit pattern of // any pointer. type uintptr uintptr // byte is an alias for uint8 and is equivalent to uint8 in all ways. It is // used, by convention, to distinguish byte values from 8-bit unsigned // integer values. type byte = uint8 // rune is an alias for int32 and is equivalent to int32 in all ways. It is // used, by convention, to distinguish character values from integer values. type rune = int32
主要注意几个点:
- type int int 大小至少32位也就是至少4字节,为什么说是至少呢?因为int类型所占字节数跟操作系统有关,如果是32位就是4个字节,如果是64位就是8个字节,type int int 和type int32 int32不同,int32永远是32位,int64永远是64位。
- type string string string可能是空,但不能为nil,这一点和Java不同,Java中String可以为null。string是不可变的,这一点和Java相同。
- type uintptr uintptr 是一个integer类型,空间足够大可存储任何指针。
- byte 和uint8类型是相同的,可以说是uint8的别称,byte更简单一些。
- rune和int32类型是相同的,rune更简单一些。
// any is an alias for interface{} and is equivalent to interface{} in all ways.
type any = interface{}
any和interface{} 是相同的,不要以为是泛型关键词,为了少写一些字母所以会用any,下面举了一个例子
func convert(t any){
switch t.(type){
case int:
//
case string:
//
case bool:
//
}
}
func main() {
f(2)
f(true)
f("煎鱼好!")
}
comparable
// comparable is an interface that is implemented by all comparable types
// (booleans, numbers, strings, pointers, channels, arrays of comparable types,
// structs whose fields are all comparable types).
// The comparable interface may only be used as a type parameter constraint,
// not as the type of a variable.
type comparable interface{ comparable }
comparable是由所有可比较类型(包括booleans, numbers, strings, pointers, channels,interface, arrays中元素为可比较类型,
以及structs 中所有属性都是可比较类型)实现的接口。只能用于类型参数约束,不用于变量类型比较,举个:
func SumNumbers[K comparable, V int](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
//入参
ints := map[string]int{
"first": 34,
"second": 12,
}
//调用
SumIntsOrFloats[string, int](ints)
- T is not an interface type and T supports the operations == and !=; or
- T is an interface type and each type in T’s type set implements comparable.
下面大多数都是上面1类型,其中interface属于上面2类型。支持的类型以下列举出来:
- Boolean values are comparable. Two boolean values are equal if they are either both true or both false.
- Integer values are comparable and ordered, in the usual way.
- Floating-point values are comparable and ordered, as defined by the IEEE-754 standard.
- Complex values are comparable. Two complex values u and v are equal if both real(u) == real(v) and imag(u) == imag(v).
- String values are comparable and ordered, lexically byte-wise.
- Pointer values are comparable. Two pointer values are equal if they point to the same variable or if both have value nil. Pointers to distinct zero-size variables may or may not be equal.
- Channel values are comparable. Two channel values are equal if they were created by the same call to make or if both have value nil.
- Interface values are comparable. Two interface values are equal if they have identical dynamic types and equal dynamic values or if both have value nil.for example interface{ ~int | ~string }
- A value x of non-interface type X and a value t of interface type T are comparable when values of type X are comparable and X implements T. They are equal if t’s dynamic type is identical to X and t’s dynamic value is equal to x.
- Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.
- Array values are comparable if values of the array element type are comparable. Two array values are equal if their corresponding elements are equal.
Java中Comparable
public interface Comparable{ public int compareTo(T o); }
iota
// iota is a predeclared identifier representing the untyped integer ordinal // number of the current const specification in a (usually parenthesized) // const declaration. It is zero-indexed. const iota = 0 // Untyped int.
- iota在关键字const出现时重置为0
- const中每新增一行常量声明将使iota计数一次,下面举了三个例子
const ( n1 = iota //0 n2 //1 n3 //2 n4 //3 ) const ( n1 = iota //0 n2 //1 _ //有误 n4 //2 ) const ( a,b = iota,iota + 1 //0,1 c,d //1,2 e,f //2,3 )
nil
// nil is a predeclared identifier representing the zero value for a // pointer, channel, func, interface, map, or slice type. var nil Type
- nil 只能为 pointer, channel, func, interface, map, or slice 类型,不能为基本数据类型
Type
// Type/Type1 is here for the purposes of documentation only. It is a stand-in // for any Go type, but represents the same type for any given function // invocation. type Type int type Type1 int // IntegerType is here for the purposes of documentation only. It is a stand-in // for any integer type: int, uint, int8 etc. type IntegerType int // FloatType is here for the purposes of documentation only. It is a stand-in // for either float type: float32 or float64. type FloatType float32 // ComplexType is here for the purposes of documentation only. It is a // stand-in for either complex type: complex64 or complex128. type ComplexType complex64
Go 为预定义标识提供的文档说明,在IDE中使用,并非真正实现,不用特别关注。
append
// The append built-in function appends elements to the end of a slice. If
// it has sufficient capacity, the destination is resliced to accommodate the
// new elements. If it does not, a new underlying array will be allocated.
// Append returns the updated slice. It is therefore necessary to store the
// result of append, often in the variable holding the slice itself:
// slice = append(slice, elem1, elem2)
// slice = append(slice, anotherSlice...)
// As a special case, it is legal to append a string to a byte slice, like this:
// slice = append([]byte("hello "), "world"...)
func append(slice []Type, elems ...Type) []Type
- append 函数只能用于slice数据结构上,将元素添加到切片末尾并返回结果
- 调用append函数只能用原来的切片变量接收返回值
- append追加元素,如果底层数组有空间的话,将新元素放在切片剩余空间中,如果底层数据没有空间,会新创建一个新的底层数组,将原来切片中元素拷贝到新切片中,返回一个新的切片,切片地址信息也会发生改变。
- append扩容原理,在一定大小内容量内cap会double增加,在大于阈值后cap按1.25倍增加,目的是节约提前分配空间。
var boys []string
//len(boys) = 4, cap(boys) = 4
boys = append(boys, "panda", "jack", "bingo", "hans")
//len(boys) = 5, cap(boys) = 8
boys = append(boys, "baobao")
girls := []string{"happy","doudou","marni"}
girls2 := []string{"jiu"}
girls = append(girls, girl2...)
intSlice := []int{1,2,3,4,5,6,7,8,9}
//4,5,6,7,8,9
intSlice2 := append(intSlice[:0],intSlice[3:]...)
//1,2,3,7,8,9
intSlice3 := append(intSlice[:3],intSlice[:6]...)
//1,2,3,4,5,6
intSlice4 := append(intSlice[:0],intSlice[:6]...)
slice1 : = []string{"hello"}
name := "world"
slice2 := []string{"goodbye"}
//编译错误,必须有接收值
append(slice1, name)
//编译错误,接收slice2不是原slice1
slice2 = append(slice1, name)
copy
// The copy built-in function copies elements from a source slice into a // destination slice. (As a special case, it also will copy bytes from a // string to a slice of bytes.) The source and destination may overlap. Copy // returns the number of elements copied, which will be the minimum of // len(src) and len(dst). func copy(dst, src []Type) int
- copy从一个切片拷贝到另一个目的切片上,原切片和目的切片可能交叉,
- copy返回复制的元素的个数,为len(src)和len(dst)中的最小值
- 注意copy函数第一个参数是目的切片,第二个参数是原切片
slice1 := []int{1,2,3,4,5}
slice2 := []int{6,7,8}
//slice1 {6,7,8,4,5} ,返回3
copy(slice1, slice2)
//slice2 {1,2,3} ,返回3
copy(slice2, slice1)
//slice2 {2,3,4} ,返回3
copy(slice2, slice1[1:4])
有点类似Java中Arrays.copy()
delete
// The delete built-in function deletes the element with the specified key // (m[key]) from the map. If m is nil or there is no such element, delete // is a no-op. func delete(m map[Type]Type1, key Type)
- delete函数用于删除map的key-value,类似于Java Map.remove(Key)操作
- delete函数第一个参数为map,第二个参数为key值,注意如果map为空或者map中没有该key,相当于没有做任何操作
- 没有返回值,并不知道是否有删除操作或者没有删除操作,需要通过map的大小来判断吗?
len / cap
// The len built-in function returns the length of v, according to its type: // Array: the number of elements in v. // Pointer to array: the number of elements in *v (even if v is nil). // Slice, or map: the number of elements in v; if v is nil, len(v) is zero. // String: the number of bytes in v. // Channel: the number of elements queued (unread) in the channel buffer; // if v is nil, len(v) is zero. // For some arguments, such as a string literal or a simple array expression, the // result can be a constant. See the Go language specification's "Length and // capacity" section for details. func len(v Type) int // The cap built-in function returns the capacity of v, according to its type: // Array: the number of elements in v (same as len(v)). // Pointer to array: the number of elements in *v (same as len(v)). // Slice: the maximum length the slice can reach when resliced; // if v is nil, cap(v) is zero. // Channel: the channel buffer capacity, in units of elements; // if v is nil, cap(v) is zero. // For some arguments, such as a simple array expression, the result can be a // constant. See the Go language specification's "Length and capacity" section for // details. func cap(v Type) int
- len函数可用于array、指向Array的指针、slice、map、string、channel
- cap函数可用于array、指向Array的指针、slice、channel,相比len少了string和map
array := [5]int{1,2,3}
//len(array)为5,cap(array)为5
arrayP := &[5]int{1,2,3}
//len(arrayP)为5,cap(arrayP)为5
map1 := map[string]int{"panda":4,"marni":3}
//len(map1)为2
//slice省略在上面append函数章节有解释
str := "hello world"
//len(str)为11
intChan = make(chan int, 3)
intChan<-10
intChan<-20
//len(intChan)为2,cap(intChan)为3
make
// The make built-in function allocates and initializes an object of type // slice, map, or chan (only). Like new, the first argument is a type, not a // value. Unlike new, make's return type is the same as the type of its // argument, not a pointer to it. The specification of the result depends on // the type: // Slice: The size specifies the length. The capacity of the slice is // equal to its length. A second integer argument may be provided to // specify a different capacity; it must be no smaller than the // length. For example, make([]int, 0, 10) allocates an underlying array // of size 10 and returns a slice of length 0 and capacity 10 that is // backed by this underlying array. // Map: An empty map is allocated with enough space to hold the // specified number of elements. The size may be omitted, in which case // a small starting size is allocated. // Channel: The channel's buffer is initialized with the specified // buffer capacity. If zero, or the size is omitted, the channel is // unbuffered. func make(t Type, size ...IntegerType) Type
- make函数用于分配内存空间,初始化对象,但是只能用于slice、map、chan类型
- make第一个参数是类型,不是值,和new函数不同的是返回的是这个类型,而不是指向这个类型的指针,下面分别讲解一下三种类型的
//len为0,cap为10 slice1 := make([]int, 0, 10) //len为10,cap为10 slice2 := make([]int,10) //map无需指定容量大小,初始化一个空map map1 := make(map[string]int) //通道缓存设置为10 channel1 := make(chan int, 10) //如果为零或忽略大小(不传入第二个参数),则 channel 为无缓冲的 channel2 := make(chan int, 0) channel3 := make(chan int)
new
// The new built-in function allocates memory. The first argument is a type, // not a value, and the value returned is a pointer to a newly // allocated zero value of that type. func new(Type) *Type
new函数是分配内存,输入的参数是类型不是值,返回值是这种类型零值的指针,下面举几个
num5 := new(int)
fmt.Printf("num5的类型=%T, num5的值=%v, num5的地址=%vn", num5, num5, &num5)
//num5的类型=*int, num5的值=0xc00018e0d0, num5的地址=0xc000186008
new(pb.ArithService)
//ArithService结构体
type ArithService struct{}
new(Call)
//Call结构体
type Call struct {
ServiceMethod string // The name of the service and method to call.
Args any // The argument to the function (*struct).
Reply any // The reply from the function (*struct).
Error error // After completion, the error status.
Done chan *Call // Receives *Call when Go is complete.
}
complex / real / imag
// The complex built-in function constructs a complex value from two // floating-point values. The real and imaginary parts must be of the same // size, either float32 or float64 (or assignable to them), and the return // value will be the corresponding complex type (complex64 for float32, // complex128 for float64). func complex(r, i FloatType) ComplexType // The real built-in function returns the real part of the complex number c. // The return value will be floating point type corresponding to the type of c. func real(c ComplexType) FloatType // The imag built-in function returns the imaginary part of the complex // number c. The return value will be floating point type corresponding to // the type of c. func imag(c ComplexType) FloatType
复数一般不会用到,不做过多解释。
close
// The close built-in function closes a channel, which must be either // bidirectional or send-only. It should be executed only by the sender, // never the receiver, and has the effect of shutting down the channel after // the last sent value is received. After the last value has been received // from a closed channel c, any receive from c will succeed without // blocking, returning the zero value for the channel element. The form // x, ok := <-c // will also set ok to false for a closed channel. func close(c chan<- Type)
- close函数用于chan,chan必须为双向通道或者是单向输入的(send-only)通道,close作用是不允许再向通道中添加元素,从通道中取出元素时不受影响的。
- 当从关闭的通道取出最后一个元素,再从通道取到的将是零值。
- x, ok := <-c 对于close来说返回ok为false。
panic
// The panic built-in function stops normal execution of the current // goroutine. When a function F calls panic, normal execution of F stops // immediately. Any functions whose execution was deferred by F are run in // the usual way, and then F returns to its caller. To the caller G, the // invocation of F then behaves like a call to panic, terminating G's // execution and running any deferred functions. This continues until all // functions in the executing goroutine have stopped, in reverse order. At // that point, the program is terminated with a non-zero exit code. This // termination sequence is called panicking and can be controlled by the // built-in function recover. func panic(v any)
- panic发生后程序会中断执行,按调用堆栈顺序层层不断向上抛,最后返回一个非0退出码,一般会返回2错误码。
- panic是底层抽象的错误,空指针、越界等异常具体异常,一般在业务代码里不要直接使用panic。
- 使用panic的场景,举个例子当项目中特别依赖一些组件时,比如一些web项目中经常会在进程启动之前初始化一些mysql,mq句柄。这些实例对业务来说是非常重要的,所以当这些实例初始化失败时我们可以直接让当前程序panic(手动panic),然后及时发现问题并解决。
- panic函数参数可以是任何类型,下面recover函数是用来处理控制panic的。
recover
// The recover built-in function allows a program to manage behavior of a // panicking goroutine. Executing a call to recover inside a deferred // function (but not any function called by it) stops the panicking sequence // by restoring normal execution and retrieves the error value passed to the // call of panic. If recover is called outside the deferred function it will // not stop a panicking sequence. In this case, or when the goroutine is not // panicking, or if the argument supplied to panic was nil, recover returns // nil. Thus the return value from recover reports whether the goroutine is // panicking. func recover() any
- recover用于处理控制paniking行为,捕捉panic,恢复程序正常执行,recover返回值为panic发生时的记录,包括panic 设置的入参和函数调用的堆栈跟踪信息。
- 如果recover放在defer函数以外,recover返回为nil,将不起控制panic的作用,下面反例1展示。
- 注意将defer语句写在函数的最前面,放在panic后面将不起作用。
defer func() {
err := recover()
if err != nil {
fmt.Println("err is", err)
}
}()
panic(errors.New("something wrong"))
//反例1,recover错误用法,此次没有panic发生,recover捕捉不到任何东西,返回nil
fmt.Printf("no panic: %vn", recover())
//反例2,引发panic,此时程序终止,不会走到下面p := recover()
panic(errors.New("something wrong"))
//不会走到此unreachale code
p := recover()
fmt.Printf("panic: %sn", p)
print / println
// The print built-in function formats its arguments in an // implementation-specific way and writes the result to standard error. // Print is useful for bootstrapping and debugging; it is not guaranteed // to stay in the language. func print(args ...Type) // The println built-in function formats its arguments in an // implementation-specific way and writes the result to standard error. // Spaces are always added between arguments and a newline is appended. // Println is useful for bootstrapping and debugging; it is not guaranteed // to stay in the language. func println(args ...Type)
- print()、println() 标准错误打印
- print()、println() 不能打印数组、结构体具体值会打印引用地址值
除非调试启动时和debug时打印日志,其他情况不建议在代码里使用
error
// The error built-in interface type is the conventional interface for
// representing an error condition, with the nil value representing no error.
type error interface {
Error() string
}
- 实现error接口的Error()方法,说明就是一个error类型,如果返回结果为nil说明没有异常。
//自定义异常结构体
type ErrInvalidParam struct {
ParamName string
ParamValue string
}
func (e *ErrInvalidParam) Error() string {
return fmt.Sprintf("invalid param: %+v, value: %+v", e.ParamName, e.ParamValue)
}
//断言机制,对ErrInvalidParam类型处理
e, ok := err.(*ErrInvalidParam)
if ok && e != nil {
//...
}
//类型选择机制,对不同类型异常处理
if err != nil {
switch err.(type) {
case *ErrInvalidParam:
//..
return
default:
//...
return
}
}



