您好,登录后才能下订单哦!
在Go语言中,make
和new
是两个用于内存分配的内建函数。尽管它们都用于分配内存,但它们的使用场景和功能有很大的不同。本文将详细探讨make
和new
的区别,并通过代码示例来帮助理解它们的具体用法。
new
函数new
函数用于分配内存,并返回一个指向该内存的指针。它接受一个类型作为参数,并返回该类型的零值的指针。
ptr := new(T)
其中,T
是任意类型,ptr
是指向T
类型零值的指针。
make
函数make
函数用于创建切片、映射和通道等引用类型的数据结构。它接受一个类型、长度和容量(对于切片和通道)作为参数,并返回一个初始化后的(非零值)的引用类型。
slice := make([]T, length, capacity)
map := make(map[K]V)
channel := make(chan T)
其中,T
是切片或通道的元素类型,K
和V
是映射的键和值类型。
new
函数的详细解析new
函数的基本用法new
函数的主要作用是分配内存并返回一个指向该内存的指针。它适用于所有类型,包括基本类型、结构体、数组等。
package main
import "fmt"
func main() {
// 分配一个int类型的零值,并返回指针
ptr := new(int)
fmt.Println(*ptr) // 输出: 0
// 分配一个结构体的零值,并返回指针
type Person struct {
Name string
Age int
}
p := new(Person)
fmt.Println(p) // 输出: &{ 0}
}
new
函数的返回值new
函数返回的是一个指向新分配内存的指针,该内存被初始化为类型的零值。对于基本类型,零值是0
、false
或""
(空字符串);对于结构体,零值是所有字段的零值。
new
函数的局限性new
函数只能分配内存并返回指针,它不会对内存进行初始化(除了零值初始化)。因此,对于引用类型(如切片、映射和通道),new
函数返回的指针指向的是零值,而不是一个可用的数据结构。
package main
import "fmt"
func main() {
// 使用new分配一个切片
slicePtr := new([]int)
fmt.Println(slicePtr) // 输出: &[]
fmt.Println(*slicePtr == nil) // 输出: true
// 使用new分配一个映射
mapPtr := new(map[string]int)
fmt.Println(mapPtr) // 输出: &map[]
fmt.Println(*mapPtr == nil) // 输出: true
// 使用new分配一个通道
chanPtr := new(chan int)
fmt.Println(chanPtr) // 输出: &<nil>
fmt.Println(*chanPtr == nil) // 输出: true
}
从上面的代码可以看出,new
函数返回的指针指向的是零值,而不是一个可用的数据结构。因此,对于引用类型,通常使用make
函数来创建可用的数据结构。
make
函数的详细解析make
函数的基本用法make
函数用于创建切片、映射和通道等引用类型的数据结构。它接受一个类型、长度和容量(对于切片和通道)作为参数,并返回一个初始化后的(非零值)的引用类型。
package main
import "fmt"
func main() {
// 创建一个切片
slice := make([]int, 5, 10)
fmt.Println(slice) // 输出: [0 0 0 0 0]
// 创建一个映射
m := make(map[string]int)
m["key"] = 42
fmt.Println(m) // 输出: map[key:42]
// 创建一个通道
ch := make(chan int, 1)
ch <- 42
fmt.Println(<-ch) // 输出: 42
}
make
函数的返回值make
函数返回的是一个初始化后的引用类型,而不是指针。对于切片,make
函数会分配底层数组并返回一个切片;对于映射,make
函数会初始化一个空的映射;对于通道,make
函数会初始化一个通道并返回。
make
函数的参数make
函数的参数取决于所创建的数据结构类型:
make([]T, length, capacity)
,其中T
是切片的元素类型,length
是切片的长度,capacity
是切片的容量(可选)。make(map[K]V)
,其中K
是键类型,V
是值类型。make(chan T, bufferSize)
,其中T
是通道的元素类型,bufferSize
是通道的缓冲区大小(可选)。make
函数的局限性make
函数只能用于创建切片、映射和通道等引用类型的数据结构。对于其他类型(如基本类型、结构体、数组等),不能使用make
函数。
package main
import "fmt"
func main() {
// 错误:不能使用make创建int类型
// i := make(int)
// 错误:不能使用make创建结构体
// type Person struct {
// Name string
// Age int
// }
// p := make(Person)
}
new
和make
的区别总结new
函数适用于所有类型,包括基本类型、结构体、数组等。make
函数仅适用于切片、映射和通道等引用类型。new
函数返回一个指向新分配内存的指针,该内存被初始化为类型的零值。make
函数返回一个初始化后的引用类型,而不是指针。new
函数只分配内存并返回指针,不会对内存进行初始化(除了零值初始化)。make
函数会分配内存并进行初始化,返回一个可用的数据结构。new
函数通常用于需要分配内存并返回指针的场景,如创建结构体指针、数组指针等。make
函数通常用于创建切片、映射和通道等引用类型的数据结构。new
创建结构体指针package main
import "fmt"
type Person struct {
Name string
Age int
}
func main() {
// 使用new创建结构体指针
p := new(Person)
p.Name = "Alice"
p.Age = 30
fmt.Println(p) // 输出: &{Alice 30}
}
make
创建切片package main
import "fmt"
func main() {
// 使用make创建切片
slice := make([]int, 5, 10)
fmt.Println(slice) // 输出: [0 0 0 0 0]
// 修改切片
slice[0] = 42
fmt.Println(slice) // 输出: [42 0 0 0 0]
}
make
创建映射package main
import "fmt"
func main() {
// 使用make创建映射
m := make(map[string]int)
m["key"] = 42
fmt.Println(m) // 输出: map[key:42]
}
make
创建通道package main
import "fmt"
func main() {
// 使用make创建通道
ch := make(chan int, 1)
ch <- 42
fmt.Println(<-ch) // 输出: 42
}
new
和make
是Go语言中用于内存分配的两个重要函数,但它们的使用场景和功能有很大的不同。new
函数适用于所有类型,返回一个指向零值的指针;而make
函数仅适用于引用类型,返回一个初始化后的数据结构。理解它们的区别和适用场景,有助于在Go语言开发中更有效地使用它们。
通过本文的详细解析和代码示例,相信读者已经对new
和make
的区别有了更深入的理解。在实际开发中,应根据具体需求选择合适的函数来分配内存和初始化数据结构。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。