在 Go 语言中,new
和 make
都是用于创建新的变量的内置函数,但它们的作用是不同的。
区别
在 Go 语言中,new
和 make
的作用是不同的:
new
用于创建一个新的变量,并返回变量的指针。make
用于创建一个新的切片、映射或通道,并返回它们的引用。
虽然 new
和 make
的作用不同,但它们都可以用于创建新的变量。下面是一个示例代码,演示了如何使用 new
和 make
创建新的变量:
package main
import "fmt"
func main() {
// 使用 new 创建一个新的整型变量
var numPtr *int = new(int)
// 使用 make 创建一个新的整型切片
var numSlice []int = make([]int, 3)
// 打印变量的值和类型
fmt.Printf("%v %T\n", numPtr, numPtr) // 输出:0x12345678 *int
fmt.Printf("%v %T\n", numSlice, numSlice) // 输出:[0 0 0] []int
}
在上面的代码中,我们使用 new
创建一个新的整型变量 numPtr
,并使用 make
创建一个新的整型切片 numSlice
。我们可以使用 fmt.Printf
函数打印变量的值和类型,发现 numPtr
是一个指针类型,指向一个值为 0 的整型变量,而 numSlice
是一个切片类型,包含三个值为 0 的整型元素。
用法
在 Go 语言中,new
和 make
的用法有以下几点需要注意:
new
new
用于创建一个新的变量,并返回变量的指针。它的语法如下:
func new(Type) *Type
其中 Type
表示要创建的变量的类型。new
函数会返回一个指向该类型变量的指针,该指针指向的变量会被初始化为零值。
下面是一个示例代码,演示了如何使用 new
创建新的变量:
package main
import "fmt"
func main() {
// 使用 new 创建一个新的整型变量
var numPtr *int = new(int)
// 使用 new 创建一个新的结构体变量
var personPtr *Person = new(Person)
// 打印变量的值和类型
fmt.Printf("%v %T\n", numPtr, numPtr) // 输出:0x12345678 *int
fmt.Printf("%v %T\n", personPtr, personPtr) // 输出:&{ 0} *main.Person
}
// 定义一个结构体类型
type Person struct {
Name string
Age int
}
在上面的代码中,我们使用 new
分别创建了一个新的整型变量 numPtr
和一个新的结构体变量 personPtr
。我们可以使用 fmt.Printf
函数打印变量的值和类型,发现 numPtr
是一个指向一个值为 0 的整型变量的指针,而 personPtr
是一个指向一个空结构体变量的指针。
make
make
用于创建一个新的切片、映射或通道,并返回它们的引用。它的语法如下:
func make(Type, size IntegerType) Type
其中 Type
表示要创建的变量的类型,size
表示类型的长度或容量(仅适用于切片和通道类型)。make
函数会返回一个新的切片、映射或通道的引用,它们会被初始化为零值。
下面是一个示例代码,演示了如何使用 make
创建新的切片、映射和通道:
package main
import "fmt"
func main() {
// 使用 make 创建一个新的整型切片
var numSlice []int = make([]int, 3)
// 使用 make 创建一个新的字符串映射
var strMap map[string]string = make(map[string]string)
// 使用 make 创建一个新的整型通道
var numChan chan int = make(chan int, 3)
// 打印变量的值和类型
fmt.Printf("%v %T\n", numSlice, numSlice) // 输出:[0 0 0] []int
fmt.Printf("%v %T\n", strMap, strMap) // 输出:map[] map[string]string
fmt.Printf("%v %T\n", numChan, numChan) // 输出:0xc00001a0c0 chan int
}
在上面的代码中,我们使用 make
分别创建了一个新的整型切片 numSlice
、一个新的字符串映射 strMap
和一个新的整型通道 numChan
。我们可以使用 fmt.Printf
函数打印变量的值和类型,发现 numSlice
是一个包含三个值为 0 的整型元素的切片,strMap
是一个空字符串映射,numChan
是一个容量为 3 的整型通道。
注意事项
在 Go 语言中,需要注意以下几点关于 new
和 make
的使用:
new
只能用于创建变量的指针类型,不能用于创建其他类型的变量。make
只能用于创建切片、映射和通道类型的变量,不能用于创建其他类型的变量。- 使用
new
创建的指针类型变量会被初始化为零值,但不会分配内存空间。 - 使用
make
创建的切片、映射和通道类型变量会被初始化为零值,并分配相应的内存空间。 - 切片、映射和通道类型的变量必须使用
make
创建,否则会导致运行时错误。
下面是一个示例代码,演示了 new
和 make
的一些注意事项:
package main
import "fmt"
func main() {
// 使用 new 创建一个新的整型变量
var numPtr *int = new(int)
// 打印指针的值
fmt.Println(numPtr) // 输出:0x12345678
// 尝试解引用一个未分配内存的指针,会导致运行时错误
// *numPtr = 123
// 使用 make 创建一个新的整型变量,会导致编译错误
// var num *int = make(int)
// 使用 make 创建一个新的整型切片
var numSlice []int = make([]int, 3)
// 打印切片的长度和容量
fmt.Printf("%v %T\n", len(numSlice), len(numSlice)) // 输出:3 int
fmt.Printf("%v %T\n", cap(numSlice), cap(numSlice)) // 输出:3 int
}
在上面的代码中,我们使用 new
创建了一个新的整型变量 numPtr
,并尝试解引用它,但会导致运行时错误,因为它并没有分配内存空间。我们还尝试使用 make
创建一个新的整型变量 num
,但会导致编译错误,因为 make
只能用于创建切片、映射和通道类型的变量。最后,我们使用 make
创建了一个新的整型切片 numSlice
,并使用 len
和 cap
函数打印了它的长度和容量。
总结
本文介绍了 Go 语言中 new
和 make
的区别、用法和注意事项,并提供了相应的示例代码。虽然 new
和 make
都用于创建新的变量