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. 洛谷 p1516 青蛙的约会 题解

    dalao们真是太强了,吊打我无名蒟蒻 我连题解都看不懂,在此篇题解中,我尽量用语言描述,不用公式推导(dalao喜欢看公式的话绕道,这篇题解留给像我一样弱的) 进入正题 如果不会扩展欧里几德的话请先 ...

  2. Docker入门笔记(Centos7)

    centos7 wget https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo vim docker-c ...

  3. nginx 日志之 access_log分割

    如果任由访问日志写下去,日志文件会变得越来越大,甚至是写满磁盘. 所以,我们需要想办法把日志做切割,比如每天生成一个新的日志,旧的日志按规定时间删除即可. 实现日志切割可以通过写shell脚本或者系统 ...

  4. Android Studio 之 ROM【2】, LiveData+ViewModel+AsyncTask+Repository

    改造上一节 ROM[1], 1.利用 LiveData<List<Word>> 与 observe 中的 onChanged 配合,删除掉之前的textView更新函数(upd ...

  5. 使用另一个版本的glibc

    glibc是Linux系统的核心库,稍有不慎就会导致系统崩溃.如果在程序中必须使用另一版本的glibc,则需要小心从事.具体来言,是在编译时指定--rpath和--dynamic-linker,而在运 ...

  6. Linux 中mysql安装(源码安装方式)

    本文是介绍以源码安装的方式编译和安装Mysql 5.6(可以指定安装路径),也可以不采用源码安装方式,直接用安装包的方式. 源码安装方式慎用,容易报错. 1.卸载旧版本 rpm -qa | grep ...

  7. 干货|Dubbo社区开发者日经验分享

    Hello,各位小伙伴大家好,我是小栈君,昨天也就是2019年10月26日,有幸在成都参加了由阿里举办的"Dubbo社区开发者日". 本次活动汇聚了各方面的大神欢聚一堂,主要是对现 ...

  8. Oracle的视图和索引

    学习笔记: ##视图     * 概念:视图就是提供一个查询的窗口,所有数据来自于原表.     * 方法:         * 查询语句创建表:             * create table ...

  9. .net core将URL请求格式化为XML或JSON(网站动态生成sitemap.xml)

    .net core将URL请求格式化为XML或JSON(网站动态生成sitemap.xml) 首先设置 Startup.cs 文件 配置 ConfigureServices services .Add ...

  10. 关于win server中 task Scheduler使用

    日常开发过程中最会遇到很多定时任务,利用计算机自带的软件工具,既方便,又快捷,能节省大量的开发时间,而且功能全面,容错率高. 下面举个例子:定时发送邮件,每天8:10准时触发邮件发送脚本 1.首先配置 ...