go语言new和make

1.new

func new(Type) *Type

    内建函数,内建函数 new 用来分配内存,它的第一个参数是一个类型,它的返回值是一个指向新分配类型默认值的指针!

2.make

func make(Type, size IntegerType) Type

     内建函数 make 用来为 slice,map chan 类型分配内存和初始化一个对象(注意:只能用在这三种类型上),跟 new 类似,第一个参数是一个类型,跟 new 不同的是,make 返回类型的引用而不是指针,而返回值也依赖于具体传入的类型

      Slice: 第二个参数 size 指定了它的长度,它的容量和长度,你可以传入第三个参数来指定不同的容量值,但必须不能比长度值小。
      比如 make([]int, 0, 10) 

     ***尤其注意append切片时,如果长度和容量指定一个数,那么追加后则在末尾,并不在首部,看下面实例

package main

import "fmt"

func main() {
	// 追加到了末尾
	mkSlice = append(mkSlice, 10)
	fmt.Println(mkSlice)

	// make切片 并追加到切片头部
	// 那么需要把长度设为0,即没有切片内容
	//  长度为0,容量为5
	mkSlice2 := make([]int, 0, 5)
	fmt.Println(mkSlice2)

	// 追加到了末尾
	mkSlice2 = append(mkSlice2, 10)
	fmt.Println(mkSlice2)
}

结果: 

[0 0 0 0 0]
[0 0 0 0 0 10]
[]
[10]

 其他切片案例使用

package main

import "fmt"

func main() {
	//s1 := make([]int, 5, 6)
	//fmt.Println(s1)
	//fmt.Println(len(s1))
	//fmt.Println(cap(s1))

	// 数组
	s2 := [3]int{1, 2, 3}
	s3 := s2 // 赋值 ,内存不同
	fmt.Println(s2, s3)
	fmt.Printf("%p\n", &s2)
	fmt.Printf("%p\n", &s3)
	fmt.Println(s2 == s3) // 注意区别,值比较
	s2[0] = 1000
	fmt.Println(s2, s3) //[1000 2 3] [1 2 3]

	fmt.Println(&s2 == &s3) // 注意区别,取得的是地址
	fmt.Printf("%v\n", s2)
	fmt.Printf("%v\n", s3)
	fmt.Println("==================")

	// 切片
	s4 := []int{1, 2, 3}
	s5 := s4 // 引用s4里的值指向一个地方
	fmt.Println(s4, s5)
	s4[0] = 1000
	fmt.Println(s4, s5) //[1000 2 3] [1000 2 3]

	fmt.Println(&s4 == &s5) // 注意区别,取得的是变量的地址
	fmt.Printf("%p\n", s4)
	fmt.Printf("%p\n", s5)

	fmt.Println("===============")
	//test()

	fmt.Printf("\n", )

	// make切片
	mkSlice := make([]int, 5)
	fmt.Println(mkSlice)

	// 追加到了末尾
	mkSlice = append(mkSlice, 10)
	fmt.Println(mkSlice)

	// make切片 并追加到切片头部
	// 那么需要把长度设为0,即没有切片内容
	//  长度为0,容量为5
	mkSlice2 := make([]int, 0, 5)
	fmt.Println(mkSlice2)

	// 追加到了末尾
	mkSlice2 = append(mkSlice2, 10)
	fmt.Println(mkSlice2)

}

func test() {
	slice0 := []string{"a", "b", "c", "d", "e"}
	fmt.Println("\n~~~~~~元素遍历~~~~~~")
	for _, ele := range slice0 {
		fmt.Print(ele, "-")
		ele = "7" // ele值改变不了切片中的值
	}

	fmt.Println("\n========")
	fmt.Println(slice0)

	fmt.Println("\n~~~~~~索引遍历~~~~~~")
	for index := range slice0 {
		fmt.Print(slice0[index], " ")
	}
	fmt.Println("\n~~~~~~元素索引共同使用~~~~~~")
	for index, ele := range slice0 {
		fmt.Print(ele, "-", slice0[index], " ")
	}
	fmt.Println("\n~~~~~~修改~~~~~~")
	for index := range slice0 {
		slice0[index] = "9"
	}
	fmt.Println(slice0)
}

      Map: 根据 size 大小来初始化分配内存,不过分配后的 map 长度为 0,如果 size 被忽略了,那么会在初始化分配内存时分配一个小尺寸的内存

map案例

package main

import "fmt"

func main() {
	//// 随机数种子
	//rand.Seed(time.Now().UnixNano())
	//
	//scoreMap := make(map[string]int, 200)
	//for i := 0; i < 100; i++ {
	//	key := fmt.Sprintf("student%02d", i)
	//	scoreMap[key] = rand.Intn(100)
	//}
	//
	//fmt.Println(scoreMap)
	//
	//// 排序map的key
	//// 按字符串排序
	//keys := make([]string, 0, 100)
	//for key := range scoreMap {
	//	keys = append(keys, key)
	//}
	//
	//sort.Strings(keys)
	//// 打印
	//for _, key := range keys {
	//	fmt.Println(key, scoreMap[key])
	//}
	var mapSlice = make([]map[string]string, 1, 3)
	for index, value := range mapSlice {
		fmt.Printf("===index:%d value:%v\n", index, value)
	}

    // 初始化
	cur := map[string]string{"name":"hahah","1212":"3333"}
	mapSlice = append(mapSlice, cur)
	for index, value := range mapSlice {
		fmt.Printf("!!!index:%d value:%v\n", index, value)
	}

	//fmt.Println("after init")
	//// 对切片中的map元素进行初始化
	//mapSlice[0] = make(map[string]string, 10)
	//mapSlice[0]["name"] = "jadeshu"
	//mapSlice[0]["password"] = "123456"
	//mapSlice[0]["address"] = "北京"
	//for index, value := range mapSlice {
	//	fmt.Printf("index:%d value:%v\n", index, value)
	//}

	//a := make([]int, 10)
	//fmt.Println(a)      //[0 0]
	//a[1] = 20
	//fmt.Println(a)
	//fmt.Println(len(a)) //2
	//fmt.Println(cap(a)) //10

	// 端口:【address,ip】
	//info := make(map[int]map[string]string, 3)
	//info[8080] = make(map[string]string,4)
	//info[8080]["address"] = "上海"
	//info[8080]["ip"] = "127.0.0.1"
	//info[6060] = make(map[string]string,4)
	//info[6060]["address"] = "北京"
	//info[6060]["ip"] = "192.168.0.101"
	//fmt.Println(info)
	//
	//testInfo:= &map[int]map[string]string{
	//	6000:{
	//		"address":"香港",
	//		"ip":"127.0.0.1",
	//	},
	//	7000:{
	//		"address":"武汉",
	//		"ip":"127.0.0.1",
	//	},
	//}
	//
	//fmt.Println(testInfo)

}

      Channel: 管道缓冲区依据缓冲区容量被初始化。如果容量为 0 或者忽略容量,管道是没有缓冲区的

 

总结

new 的作用是初始化一个指向类型的指针(*T),make 的作用是为 slice,map 或 chan 初始化并返回引用(T)。

posted @ 2019-11-05 20:42  jadeshu  阅读(107)  评论(0编辑  收藏  举报