1. 综述

变量声明时未赋初值,则变量被自动赋值为该类型的零值(固定值)

func new(Type) *Type

new()返回一个指针,指向新分配的该类型的零值,不是空指针(nil)。the value returned is a pointer to a newly allocated zero value of that type.

func make(t Type, size ...IntegerType) Type

make()只适用于slice、map、chan,此三种类型创建时推荐使用make()而不是new()。The make built-in function allocates and initializes an object of type slice, map, or chan (only). 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, , ) allocates an underlying array of size  and returns a slice of length  and capacity  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.

如下将按照类型实体、指针、new/make、类型比较等详述各种数据类型。

2. 数组

数组是值类型而不是引用类型。当数组赋值给一个变量时,该变量会得到一个原始数组的副本。对新变量的更改,不会影响原始数组。

数组实体被初始化数组值类型的零值,如int零值为0,string零值为""。

数组指针初始化为nil。

new()返回指向类型零值的指针。

数组是值类型,可以直接比较。

package main

import (
"fmt"
"strconv"
) func main(){
var ai []int
var as []string
fmt.Printf("int array [%p] init value: %v\n", &ai, ai)
fmt.Printf("string array [%p] init value: %v\n", &as, as)
fmt.Println("---------------------------") var i int
for i = ; i < len(ai); i++ {
ai[i] = + i
} for i, _ := range as {
as[i] = strconv.Itoa( + i)
}
fmt.Printf("int array [%p] init value: %v\n", &ai, ai)
fmt.Printf("string array [%p] init value: %v\n", &as, as)
fmt.Println("---------------------------") var pai *[]int
var pas *[]string
fmt.Printf("int point array [%p] init value: %v\n", &pai, pai)
fmt.Printf("string point array [%p] init value: %v\n", &pas, pas)
fmt.Println("---------------------------") pai = &ai
pas = &as
pai[] =
pas[] = ""
fmt.Printf("int point array [%p] init value: %v\n", &pai, *pai)
fmt.Printf("string point array [%p] init value: %v\n", &pas, *pas)
fmt.Println("---------------------------") paii := new([]int)
pass := new([]string)
fmt.Printf("int point array [%p] init value: %v\n", &paii, *paii)
fmt.Printf("string point array [%p] init value: %v\n", &pass, *pass)
fmt.Println("---------------------------") for i = ; i < len(*paii); i++ {
paii[i] = + i
}
for i, _ := range *pass {
pass[i] = strconv.Itoa( + i)
}
fmt.Printf("int point array [%p] init value: %v\n", &paii, *paii)
fmt.Printf("string point array [%p] init value: %v\n", &pass, *pass)
fmt.Println("---------------------------") paii[] =
pass[] = ""
fmt.Printf("%v\n==\n%v \n???\n%t\n", ai, *paii, (ai==*paii))
fmt.Println("---------------------------")
fmt.Printf("%v\n==\n%v \n???\n%t\n", as, *pass, (as==*pass))
}

运行结果:

int array [0xc000072000] init value: [         ]
string array [0xc000074000] init value: [ ]
---------------------------
int array [0xc000072000] init value: [ ]
string array [0xc000074000] init value: [ ]
---------------------------
int point array [0xc00000e030] init value: <nil>
string point array [0xc00000e038] init value: <nil>
---------------------------
int point array [0xc00000e030] init value: [ ]
string point array [0xc00000e038] init value: [ ]
---------------------------
int point array [0xc00000e040] init value: [ ]
string point array [0xc00000e048] init value: [ ]
---------------------------
int point array [0xc00000e040] init value: [ ]
string point array [0xc00000e048] init value: [ ]
---------------------------
[ ]
==
[ ]
???
true
---------------------------
[ ]
==
[ ]
???
true

3. 切片

切片是值类型而不是引用类型。切片本身不拥有任何数据,只是对现有数组的引用。对切片的所有修改都会反映到底层数组上。

切片实体初始化为切片类型的零值 nil。一个 nil 切片的长度和容量为 0。

切片指针初始化为nil。

make返回类型零值的切片,非nil。

切片只能和nil作比较,要比较切片需比较切片的每个元素值。

package main

import (
"fmt"
"strconv"
) func main(){
var si []int
var ss []string
fmt.Printf("int slice [%p] init value: %v, len:%d, cap:%d\n", &si, si, len(si), cap(si))
fmt.Printf("string slice [%p] init value: %v, len:%d, cap:%d\n", &ss, ss, len(ss), cap(ss))
// fmt.Printf("int slice [%p] init value: %v\n", &si, si[0])
// fmt.Printf("string slice [%p] init value: %v\n", &ss, ss[0])
fmt.Println("---------------------------------------") var i int
if si == nil {
for i = ; i < ; i++ {
si = append(si, +i)
fmt.Printf("int slice [%p] append %d element: %v, len:%d, cap:%d\n", &si, i, si, len(si), cap(si))
}
}
fmt.Println("---------------------------------------")
if ss == nil {
for i = ; i < ; i++ {
ss = append(ss, strconv.Itoa(+i))
fmt.Printf("string slice [%p] append %d element: %v, len:%d, cap:%d\n", &ss, i, ss, len(ss), cap(ss))
}
}
fmt.Println("---------------------------------------") var psi *[]int
var pss *[]string
// fmt.Printf("int slice pointer [%p] init value: %v, len:%d, cap:%d\n", &psi, psi, len(*psi), cap(*psi))
// fmt.Printf("string slice pointer [%p] init value: %v, len:%d, cap:%d\n", &pss, pss, len(*pss), cap(*pss))
fmt.Printf("int slice pointer [%p] init value: %v\n", &psi, psi)
fmt.Printf("string slice pointer [%p] init value: %v\n", &pss, pss)
fmt.Println("---------------------------------------")
psi = &si
pss = &ss
fmt.Printf("int slice pointer [%p] init value: %v, len:%d, cap:%d\n", &psi, *psi, len(*psi), cap(*psi))
fmt.Printf("string slice pointer [%p] init value: %v, len:%d, cap:%d\n", &pss, *pss, len(*pss), cap(*pss))
fmt.Println("---------------------------------------") sim := make([]int, , )
ssm := make([]string, , )
fmt.Printf("int slice make [%p] init value: %v, len:%d, cap:%d\n", &sim, sim, len(sim), cap(sim))
fmt.Printf("string slice make [%p] init value: %v, len:%d, cap:%d\n", &ssm, ssm, len(ssm), cap(ssm))
fmt.Println("---------------------------------------") for i = ; i < len(sim); i++ {
sim[i] = + i
}
for i,_ := range ssm {
ssm[i] = strconv.Itoa(+i)
}
fmt.Printf("int slice make [%p] init value: %v, len:%d, cap:%d\n", &sim, sim, len(sim), cap(sim))
fmt.Printf("string slice make [%p] init value: %v, len:%d, cap:%d\n", &ssm, ssm, len(ssm), cap(ssm))
fmt.Println("---------------------------------------") // fmt.Printf("%v\n==\n%v\n???\n%t\n", si, *psi, (si==*psi))
fmt.Println("---------------------------------------")
// fmt.Printf("%v\n==\n%v\n???\n%t\n", ss, ssm, (ss==ssm)) }

运行结果:

int slice [0xc00006a020] init value: [], len:, cap:
string slice [0xc00006a040] init value: [], len:, cap:
---------------------------------------
int slice [0xc00006a020] append element: [], len:, cap:
int slice [0xc00006a020] append element: [ ], len:, cap:
int slice [0xc00006a020] append element: [ ], len:, cap:
int slice [0xc00006a020] append element: [ ], len:, cap:
int slice [0xc00006a020] append element: [ ], len:, cap:
int slice [0xc00006a020] append element: [ ], len:, cap:
int slice [0xc00006a020] append element: [ ], len:, cap:
int slice [0xc00006a020] append element: [ ], len:, cap:
int slice [0xc00006a020] append element: [ ], len:, cap:
int slice [0xc00006a020] append element: [ ], len:, cap:
---------------------------------------
string slice [0xc00006a040] append element: [], len:, cap:
string slice [0xc00006a040] append element: [ ], len:, cap:
string slice [0xc00006a040] append element: [ ], len:, cap:
string slice [0xc00006a040] append element: [ ], len:, cap:
string slice [0xc00006a040] append element: [ ], len:, cap:
string slice [0xc00006a040] append element: [ ], len:, cap:
string slice [0xc00006a040] append element: [ ], len:, cap:
string slice [0xc00006a040] append element: [ ], len:, cap:
string slice [0xc00006a040] append element: [ ], len:, cap:
string slice [0xc00006a040] append element: [ ], len:, cap:
---------------------------------------
int slice pointer [0xc00007e020] init value: <nil>
string slice pointer [0xc00007e028] init value: <nil>
---------------------------------------
int slice pointer [0xc00007e020] init value: [ ], len:, cap:
string slice pointer [0xc00007e028] init value: [ ], len:, cap:
---------------------------------------
int slice make [0xc00006a340] init value: [ ], len:, cap:
string slice make [0xc00006a360] init value: [ ], len:, cap:
---------------------------------------
int slice make [0xc00006a340] init value: [ ], len:, cap:
string slice make [0xc00006a360] init value: [ ], len:, cap:
---------------------------------------
---------------------------------------

4. map

Map是引用类型,当 map 被赋值为一个新变量的时候,它们指向同一个内部数据结构。因此,改变其中一个变量,就会影响到另一变量。

map的零值是nil,不能插入元素。map没有容量的概念,其长度为目前元素的个数。

只要map不为nil就可以无限插入元素。“map[]=”插入元素。

map实体初始化为nil。需要make()或“=map[int]int{}”进行初始化后才能加元素。

map指针初始化为nil。

make返回类型零值的map,且长度为0,无论make中是否指定len或指定len大小。

map只能和nil作比较。要比较map,需比较两个map的每个元素。

package main

import (
"fmt"
"strconv"
) func main(){
var mi map[int]int
var ms map[string]string
fmt.Printf("int map [%p] init value: %v, len:%d\n", &mi, mi, len(mi))
fmt.Printf("string map [%p] init value: %v, len:%d\n", &ms, ms, len(ms))
fmt.Println("-------------------------------") var i int
if mi == nil {
mi = make(map[int]int)
fmt.Printf("int map make [%p] init value: %v, len:%d\n", &mi, mi, len(mi))
for i = ; i < ; i++ {
mi[i] = + i
fmt.Printf("int map make [%p] init %d value: %v, len:%d\n", &mi, i, mi, len(mi))
}
}
fmt.Println("-------------------------------") if ms == nil {
ms = make(map[string]string, )
fmt.Printf("string map make [%p] init value: %v, len:%d\n", &ms, ms, len(ms))
for i = ; i < ; i++ {
k := strconv.Itoa(+i)
ms[k] = strconv.Itoa(+i)
fmt.Printf("string map make [%p] init [%v] value: %v, len:%d\n", &ms, k, ms, len(ms))
}
}
fmt.Println("-------------------------------") var pmi *map[int]int
var pms *map[string]string
// fmt.Printf("int map pointer [%p] init value: %v, len:%d\n", &pmi, pmi, len(*pmi))
// fmt.Printf("string map pointer [%p] init value: %v, len:%d\n", &pms, pms, len(*pms))
fmt.Printf("int map pointer [%p] init value: %v\n", &pmi, pmi)
fmt.Printf("string map pointer [%p] init value: %v\n", &pms, pms)
fmt.Println("-------------------------------") pmi = &mi
pms = &ms
fmt.Printf("int map pointer [%p] init value: %v, len:%d\n", &pmi, pmi, len(*pmi))
fmt.Printf("string map pointer [%p] init value: %v, len:%d\n", &pms, pms, len(*pms))
fmt.Println("-------------------------------") // fmt.Printf("%v\n==%v\n???\n%t\n", mi, *pmi, (mi==*pmi))
fmt.Println("-------------------------------")
// fmt.Printf("%v\n==%v\n???\n%t\n", ms, *pms, (ms==*pms)) var mii map[int]int = map[int]int{}
var mss map[string]string = map[string]string{}
fmt.Printf("int map [%p] init value: %v, len:%d\n", &mii, mii, len(mii))
fmt.Printf("string map [%p] init value: %v, len:%d\n", &mss, mss, len(mss))
fmt.Println("-------------------------------") for i = ; i < ; i++ {
mii[i] = + i
} for i = ; i < ; i++ {
k := strconv.Itoa(+i)
mss[k] = strconv.Itoa(+i)
}
fmt.Printf("int map [%p] init value: %v, len:%d\n", &mii, mii, len(mii))
fmt.Printf("string map [%p] init value: %v, len:%d\n", &mss, mss, len(mss))
fmt.Println("-------------------------------")
}

运行结果:

int map [0xc00007e018] init value: map[], len:
string map [0xc00007e020] init value: map[], len:
-------------------------------
int map make [0xc00007e018] init value: map[], len:
int map make [0xc00007e018] init value: map[:], len:
int map make [0xc00007e018] init value: map[: :], len:
int map make [0xc00007e018] init value: map[: : :], len:
int map make [0xc00007e018] init value: map[: : : :], len:
int map make [0xc00007e018] init value: map[: : : : :], len:
int map make [0xc00007e018] init value: map[: : : : : :], len:
int map make [0xc00007e018] init value: map[: : : : : : :], len:
int map make [0xc00007e018] init value: map[: : : : : : : :], len:
int map make [0xc00007e018] init value: map[: : : : : : : : :], len:
int map make [0xc00007e018] init value: map[: : : : : : : : : :], len:
-------------------------------
string map make [0xc00007e020] init value: map[], len:
string map make [0xc00007e020] init [] value: map[:], len:
string map make [0xc00007e020] init [] value: map[: :], len:
string map make [0xc00007e020] init [] value: map[: : :], len:
string map make [0xc00007e020] init [] value: map[: : : :], len:
string map make [0xc00007e020] init [] value: map[: : : : :], len:
string map make [0xc00007e020] init [] value: map[: : : : : :], len:
string map make [0xc00007e020] init [] value: map[: : : : : : :], len:
string map make [0xc00007e020] init [] value: map[: : : : : : : :], len:
string map make [0xc00007e020] init [] value: map[: : : : : : : : :], len:
string map make [0xc00007e020] init [] value: map[: : : : : : : : : :], len:
-------------------------------
int map pointer [0xc00007e030] init value: <nil>
string map pointer [0xc00007e038] init value: <nil>
-------------------------------
int map pointer [0xc00007e030] init value: &map[: : : : : : : : : :], len:
string map pointer [0xc00007e038] init value: &map[: : : : : : : : : :], len:
-------------------------------
-------------------------------
int map [0xc00007e040] init value: map[], len:
string map [0xc00007e048] init value: map[], len:
-------------------------------
int map [0xc00007e040] init value: map[: : : : : : : : : :], len:
string map [0xc00007e048] init value: map[: : : : : : : : : :], len:
-------------------------------

5. struct

结构体是值类型,可以直接用=赋值。

结构体实体初始化为每个成员的零值,仅为某些字段指定初始值时,忽略的字段会赋值为零值。

结构体指针值为nil。

new()返回指向类型零值的指针。

如果它的每一个字段都是可比较的,则该结构体也是可比较的。如果两个结构体变量的对应字段相等,则这两个变量也是相等的。如果结构体包含不可比较的字段,则结构体变量也不可比较。

map可以以指针和实体方式返回,函数返回后可以通过返回值访问到原来函数内部的结构体(即函数内部的结构体不会随着函数结束而被回收)。

package main

import (
"fmt"
) type People struct {
Name string
Phone string
Addr []string
} func main(){
var pStruct People
// if pStruct == nil {
// fmt.Println("var initvalue is null")
// } else {
fmt.Println("var initvalue init: ",pStruct)
fmt.Println("var initvalue init: Name: ", pStruct.Name)
fmt.Println("var initvalue init: Name: ", pStruct.Phone)
fmt.Println("var initvalue init: Name: ", pStruct.Addr, ", len:", len(pStruct.Addr))
pStruct = People{"wang", "", []string{"Beijing", "Shanghai"}}
fmt.Println("after var initvalue init: ", pStruct)
// }
fmt.Println("-------------------------------------------") var p *People
if p == nil {
fmt.Println("pointer initvalue is null")
} else {
fmt.Println("pointer initvalue is ", p)
} fmt.Println("-------------------------------------------")
peo := new(People)
if peo == nil {
fmt.Println("new struct initvalue is null")
} else {
fmt.Println("new struct initvalue is ", peo)
peo.Name = "wang"
peo.Phone = ""
fmt.Println("after new struct initvalue is ", peo)
}
fmt.Println("-------------------------------------------") tmp, _ := testReturn()
fmt.Printf("return [%p] value: %v\n", &tmp, tmp)
fmt.Println("-------------------------------------------") ptmp, _ := testReturnPointer()
fmt.Printf("return pointer [%p]:[%p] value: %v\n", &ptmp, ptmp, *ptmp)
fmt.Println("-------------------------------------------")
}
func testReturnPointer()(*People, error){
tmp := People{}
tmp.Name = "wang"
tmp.Phone = ""
fmt.Printf("In function, return pointer [%p] value: %v\n", &tmp, tmp)
return &tmp, nil
} func testReturn()(People, error){
tmp := People{}
tmp.Name = "wang"
tmp.Phone = ""
fmt.Printf("In function, return [%p] value: %v\n", &tmp, tmp)
return tmp, nil
}

运行结果:

var initvalue init:  {  []}
var initvalue init: Name:
var initvalue init: Name:
var initvalue init: Name: [] , len:
after var initvalue init: {wang [Beijing Shanghai]}
-------------------------------------------
pointer initvalue is null
-------------------------------------------
new struct initvalue is &{ []}
after new struct initvalue is &{wang []}
-------------------------------------------
In function, return [0xc0000841c0] value: {wang []}
return [0xc000084180] value: {wang []}
-------------------------------------------
In function, return pointer [0xc000084280] value: {wang []}
return pointer [0xc00007e020]:[0xc000084280] value: {wang []}
-------------------------------------------

golang之类型零值初始化及比较的更多相关文章

  1. Aggregate类型以及值初始化

    引言 在C++中,POD是一个极其重要的概念.要理解POD类型,我们首先需要理解Aggregate类型.下文结合stackoverflow上的高票回答将对Aggregate类型做一个全面的解读. 对于 ...

  2. 零值初始化&字符串常数作为函数模板参数

    1.在定义一个局部变量时,并希望该局部变量的初始化一个值,可以显示调用其默认构造函数,使其值为0(bool类型默认值为false). template <typename T> void ...

  3. golang基础--类型与变量

    基础知识--类型与变量 基本类型 布尔型:bool 长度: 1字节 取值范围: false, true 注意事项: 不可以使用数字代表,不像 python中可是使用 1和0表示 整型: int/uin ...

  4. 【Go入门教程2】内置基础类型(Boolean、数值、字符串、错误类型),分组,iota枚举,array(数值),slice(切片),map(字典),make/new操作,零值

    这小节我们将要介绍如何定义变量.常量.Go内置类型以及Go程序设计中的一些技巧. 定义变量 Go语言里面定义变量有多种方式. 使用var关键字是Go最基本的定义变量方式,与C语言不同的是Go把变量类型 ...

  5. 【Go入门教程4】变量(var),常量(const),内置基础类型(Boolean、数值 byte,int,rune、字符串、错误类型),分组,iota枚举,array(数值),slice(切片),map(字典),make/new操作,零值

    这小节我们将要介绍如何定义变量.常量.Go 内置类型以及 Go 程序设计中的一些技巧. 定义变量 Go 语言里面定义变量有多种方式. 使用 var 关键字是 Go 最基本的定义变量方式,与 C 语言不 ...

  6. GO学习笔记 - 变量在定义时没有明确的初始化时会赋值为“零值 ”。

    官方教程:https://tour.go-zh.org/basics/12 变量在定义时没有明确的初始化时会赋值为 零值 . 零值是: 数值类型为 0 , 布尔类型为 false , 字符串为 &qu ...

  7. Golang使用proto3协议导致零值字段不显示

    Golang使用proto3协议导致零值字段不显示 问题描述 proto协议生成的结构体如果使用直接转成json会导致零值字段不显示,这样的json是有毛病的,可以使用如下方法解决 示例Demo pa ...

  8. Golang - 复合类型

    目录 Golang - 复合类型 1. 指针 2. new()和make() 3. 数组 4. slice 5. Map 6. 结构体 7. 结构体参数 Golang - 复合类型 1. 指针 go语 ...

  9. golang枚举类型 - iota用法拾遗

    在c#.java等高级语言中,经常会用到枚举类型来表示状态等.在golang中并没有枚举类型,如何实现枚举呢?首先从枚举的概念入手. 1.枚举类型定义 从百度百科查询解释如下:http://baike ...

随机推荐

  1. NDCG、AUC介绍

    https://blog.csdn.net/u014313009/article/details/38944687 SIGIR的一篇推荐算法论文中提到用NDCG和AUC作为比较效果的指标,之前没了解过 ...

  2. [300iq Contest 1-D]Dates

    传送门 Description 每个妹子匹配一个时间区间,每个时间最多选择\(a_i\)个妹子,每个妹子有一个快乐值,最大化总快乐值 Solution 贪心,从大往小取,能取则取 判断是否可以有完美匹 ...

  3. Servlet 4.0 入门

    Java™ Servlet API 是主流服务器端 Java 的基本构建块,也是 Java EE 技术的一部分,例如,用于 Web 服务的 JAX - RS.JSF (JavaServer Faces ...

  4. 第10课 面向对象的增强(default/delete、override/final)

    一.default和delete关键字 (一)编译器提供的“缺省函数” 1.类的成员函数:构造/析构函数.复制构造/复制赋值函数.移动构造/移动赋值函数. 2. 类的全局默认操作函数:operator ...

  5. docker-compose可持续集成之jenkins

    1.下载docker-compose curl -L https://get.daocloud.io/docker/compose/releases/download/1.24.1/docker-co ...

  6. Alpha冲刺(11/10)——2019.5.3

    作业描述 课程 软件工程1916|W(福州大学) 团队名称 修!咻咻! 作业要求 项目Alpha冲刺(团队) 团队目标 切实可行的计算机协会维修预约平台 开发工具 Eclipse 团队信息 队员学号 ...

  7. SQL join 三种扩展用法

    以前学习,只知道  LEFT JOIN.RIGHT JOIN.INNER JOIN.FULL  JOIN,共四种集合,然而加上一些条件,可以组合成另外三种集合,直接上图.

  8. spring boot 从开发到部署(二)—重启服务

    上篇中,我们开发并部署上线了一个 spring boot 项目.现在需要编写服务重启脚本,保证服务器重启后能够自动的运行我们的项目. /home/web/sprint-web/restart-happ ...

  9. 了解编程语言 ----- c# 简介

    1.编程语言 编程语言: 为了实现人与机器的交互,计算机主要识别的就是 0 和 1 语言的发展过程主要分为: 1.面向机器的语言:二进制,汇编 2.面向过程的语言:汇编语言,C语言,B语言, 3.基于 ...

  10. [转帖]中国首颗通信能力达10Gbps的低轨宽带卫星出厂

    中国首颗通信能力达10Gbps的低轨宽带卫星出厂 From 新浪科技 原来卫星都能够达到10G带宽了 我们公司的工位还TM有百兆的呢. 近日,中国首颗通信能力可达到10Gbps的5G低轨宽带卫星正式出 ...