Go语言拥有一些不需要进行导入操作就可以使用的内置函数。它们有时可以针对不同的类型操作,例如:len、cap 和 append,或必须用于系统级的操作,例如:panic。因此,它们需要直接获得编译器的支持。
go1.13.7 版本下载地址:
https://golang.org/dl/
源文件builtin.go文件中一共定义了15个内置函数。下面来看看builtin.go文件
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
Package builtin provides documentation for Go's predeclared identifiers.
The items documented here are not actually in package builtin
but their descriptions here allow godoc to present documentation
for the language's special identifiers.
*/
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
// 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.
// nil is a predeclared identifier representing the zero value for a
// pointer, channel, func, interface, map, or slice type.
var nil Type // Type must be a pointer, channel, func, interface, map, or slice type
// Type 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
// 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 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
// 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
// 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
// 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)
// 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
// 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
// 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
// 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
// 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)
// 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 interface{})
// 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() interface{}
// 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)
// 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
}
append
append内置函数将元素追加到片的末尾。如果它有足够的容量,则重新分配目的地以容纳新元素。如果没有,将分配一个新的底层数组。
func append(slice []Type, elems ...Type) []Type
append用法:
1、slice = append(slice, elem1, elem2)
2、slice = append(slice, anotherSlice...)
例子:
package main
import (
"fmt"
)
func main() {
var a []string
b := append(a, "a")
fmt.Println(b)
c := append(b, "b", "c", "d", "e")
fmt.Println(c)
x := []int {1,2,3}
y := []int {4,5,6}
fmt.Println(append(x,4,5,6))
fmt.Println(append(x,y...));
}
编译结果:
第一种用法中,第一个参数为slice,后面可以添加多个参数。第二种slice的名称后面加三个点,而且这时候append只支持两个参数,不支持任意个数的参数。
copy
copy内置函数将元素从源片复制到目标片。
func copy(dst, src []Type) int
用于将源slice的数据(第二个参数),复制到目标slice(第一个参数)。
例子:
package main
import (
"fmt"
)
func main() {
var a = []int{0, 1, 2, 3, 4, 5, 6, 7}
var s = make([]int, 6)
//源长度为8,目标为6,只会复制前6个
n1 := copy(s, a)
fmt.Println("s - ", s)
fmt.Println("n1 - ", n1)
//源长为7,目标为6,复制索引1到6
n2 := copy(s, a[1:])
fmt.Println("s - ", s)
fmt.Println("n2 - ", n2)
}
delete内置函数从映射中删除具有指定键// (mfkeyl)的元素。如果m是nil,或者不存在这样的元素,则删除。
func delete(m map[Type]Type1, key Type)
例子:
package main
import (
"fmt"
)
func main() {
map1 := make(map[string]int)
map1["one"] = 100
map1["two"] = 200
map1["three"] = 300
map1["four"] = 400
fmt.Println(map1, len(map1))
delete(map1, "two")
fmt.Println(map1, len(map1))
}
func len(v Type) int
如果 v 是数组:返回的是数组的元素个数。
如果 v 是个指向数组的指针:返回的是 *v 的元素个数。
如果 v 是 slice 或者 map :返回 v 的元素个数。
例子:
package main
import "fmt"
func main() {
var arr1 [5]int
for i:=0; i < len(arr1); i++ {
arr1[i] = i * 2
}
for i:=0; i < len(arr1); i++ {
fmt.Printf("Array at index %d is %d\n", i, arr1[i])
}
}
func cap(v Type) int
数组:返回的是数组的元素个数,同 len(v)
指向数组的指针:返回的是 *v 的元素个数,同 len(v)
slice:返回的是 slice 最大容量,>=len(v)
package main
import "fmt"
func main() {
var slice1 []int = make([]int, 10)
for i := 0; i < len(slice1); i++ {
slice1[i] = 5 * i
}
for i := 0; i < len(slice1); i++ {
fmt.Printf("Slice at %d is %d\n", i, slice1[i])
}
fmt.Printf("\nThe length of slice1 is %d\n", len(slice1))
fmt.Printf("The capacity of slice1 is %d\n", cap(slice1))
}
编译结果:
func make(t Type, size ...IntegerType) Type
make内置函数分配并初始化类型为slice、map或chan(仅)的对象。与new一样,第一个参数是类型,而不是值。与new不同,make的返回类型与其参数的类型相同,而不是指向它的指针。
例子:
package main
import "fmt"
func main() {
slice1 := make([]int, 0, 10)
for i := 0; i < cap(slice1); i++ {
slice1 = slice1[0:i+1]
slice1[i] = i
fmt.Printf("The length of slice is %d\n", len(slice1))
}
// 打印 slice:
for i := 0; i < len(slice1); i++ {
fmt.Printf("Slice at %d is %d\n", i, slice1[i])
}
}
func new(Type) *Type
new内置函数分配内存。第一个参数是类型,而不是值,返回的值是指向该类型新分配的零值的指针。
例子:
package main
import (
"fmt"
)
func main() {
i := new(int)
s := new(string)
arr := new([5]string)
slice := new([]string)
mp := new(map[string]string)
ch := new(chan int)
fmt.Printf("i type is %T\n", i)
fmt.Printf("s type is %T,len is %v\n", s, len(*s))
fmt.Printf("arr type is %T,len is %v\n", arr, len(*arr))
fmt.Printf("slice type is %T,len is %v\n", slice, len(*slice))
fmt.Printf("mp type is %T,len is %v\n", mp, len(*mp))
fmt.Printf("ch type is %T,len is %v\n", ch, len(*ch))
}
func complex(r, i FloatType) ComplexType
func real(c ComplexType) FloatType
func imag(c ComplexType) FloatType
使用内置的 complex 函数构建复数,并使用 real 和 imag 函数返回复数的实部和虚部:
例子:
package main
import (
"fmt"
)
func main() {
var x complex128 = complex(1, 2) // 1+2i
var y complex128 = complex(3, 4) // 3+4i
fmt.Println(x*y) // "(-5+10i)"
fmt.Println(real(x*y)) // "-5"
fmt.Println(imag(x*y)) // "10"
}
func close(c chan<- Type)
close内置函数关闭一个通道,该通道必须是双向的或仅限发送的。它应该只由发送方执行,而不是由接收方执行,并且在接收到最后发送的值后关闭通道。
panic、recover
func panic(v interface{})
假如函数F中书写了panic语句,会终止其后要执行的代码,在panic所在函数F内如果存在要执行的defer函数列表,按照defer的逆序执行。
返回函数F的调用者G,在G中,调用函数F语句之后的代码不会执行,假如函数G中存在要执行的defer函数列表,按照defer的逆序执行,这里的defer 有点类似 try-catch-finally 中的 finally。
func recover() interface{}
恢复内置功能允许程序管理恐慌的goroutine的行为。执行一个调用来恢复一个延迟的函数(但不是由它调用的任何函数)将停止恐慌序列y恢复正常执行,并检索传递给all panic的错误值。如果在deferred函数之外调用recover,它将不会停止一个令人恐慌的序列。
简单来讲:go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理。
例子:
package main
import (
"fmt"
)
func main() {
fmt.Println("c")
defer func() { // 必须要先声明defer,否则不能捕获到panic异常
fmt.Println("d")
if err := recover(); err != nil {
fmt.Println(err) // 这里的err其实就是panic传入的内容
}
fmt.Println("e")
}()
f() //开始调用f
fmt.Println("f") //这里开始下面代码不会再执行
}
func f() {
fmt.Println("a")
panic("异常信息")
fmt.Println("b") //这里开始下面代码不会再执行
}
编译结果:
注意:利用recover处理panic指令,defer必须在panic之前声明,否则当panic时,recover无法捕获到panic。
print、println
func print(args ...Type)
func println(args ...Type)
参考:
Go入门指南
go1.13.7版本源码builtin.go
喜欢本文的朋友,欢迎关注微信公众号(图一) “程序猿编码” 收看更多精彩文章。扫码二维码(图二),添加本人微信。备注:加群。即可加入“程序猿编码”交流群。