for i,value range slice{
}
//方式一
ages:=make(map[string]int)
//方式二
ages:=map[string]int{
“alice”:31,
“charlies”:34,
}
//delete 一个元素
delete(ages,"alice")
ages["bob"] = ages["bob"] + 1 //如果没有bob会返回0
ages["bob"] += 1
ages["bob"]++
_ = &ages["bob"] //无法进行取地址操作,并非是变量
for name, age := range ages {
fmt.Printf("%s\t%d\n", name, age)
} //遍历操作
var names []string
for name := range ages {
names = append(names, name)
}
sort.Strings(names)
for _, name := range names {
fmt.Printf("%s\t%d\n", name, ages[name])
}
查看是否存在在map中
age,ok:=ages["bob"]
if !ok{ bob is not a key in this map}
//一般这样用:
if age, ok := ages["bob"]; !ok { /* ... */ }
type Point struct{
X,Y int
}
type Circle struct{
Point
Radius int
}
type Wheel struct{
Circle
Spokes int
}
var w Wheel
w.X=8 // =w.Circle.Point.X
w.Radius=5
w=Wheel{8,8,5,20} //无效
w=Wheel{x:8,Y:8 ...} //无效
w=Wheel{Circle{Point{8,8},5},20} //可以
因为匿名成员也有一个隐式的名字,因此不能同时包含两个类型相同的匿 名成员,这会导致名字冲突。同时,因为成员的名字是由其类型隐式地决定的, 所有匿名成员也有可见性的规则约束。
encoding/json、encoding/xml、encoding/asn1等包
type Movie struct{
Title string
Year int `json:"released"`
Color bool `json:"color,omitempty"`
Actors []string
}
var movies=[]Movie{
{Title:"CASEL",Year:1942,Color:false,
Actors:[]string{"humphrey Bogart","Ingrid Bergman"}},
{Title:"CASEL",Year:1942,Color:false,
Actors:[]string{"humphrey Bogart","Ingrid Bergman"}},
}
这样的数据结构特别适合 JSON 格式,并且在两种之间相互转换也很容易。 将一个 Go 语言中类似 movies 的结构体 slice 转为 JSON 的过程叫编组 (marshaling)。编组通过调用 json.Marshal 函数完成:
data,err:=json.Marshal(movies)
if err!=nil{
log.Fatalf("JSON marshaling failed:%s",err)
}
fmt.Printf("%s\n",data)
Marshal函数返还一个编码后的字节slice,包含很长的字符串,并且没 有空白缩进;我们将它折行以便于显示:
[{"Title":"Casablanca","released":1942,"Actors":["Humphrey
Bogart","Ingr
id Bergman"]},{"Title":"Cool Hand
Luke","released":1967,"color":true,"Ac tors":["Paul
Newman"]},{"Title":"Bullitt","released":1968,"color":true," Actors":["Steve McQueen","Jacqueline Bisset"]}]
这种紧凑的表示形式虽然包含了全部的信息,但是很难阅读。为了生成便 于阅读的格式,另一个 json.MarshalIndent 函数将产生整齐缩进的输出。 该函数有两个额外的字符串参数用于表示每一行输出的前缀和每一个层级的 缩进:
data, err := json.MarshalIndent(movies, "", " ") if err != nil {
log.Fatalf("JSON marshaling failed: %s", err)
}
fmt.Printf("%s\n", data)
输出为:
[
{
"Title": "Casablanca",
"released": 1942, "Actors": [
"Humphrey Bogart",
"Ingrid Bergman"
]
},
{
"Title": "Cool Hand Luke",
...
在编码时,默认使用 Go 语言结构体的成员名字作为 JSON 的对象(通过 reflect 反射技术,我们将在 12.6 节讨论)。只有导出的结构体成员才会被 编码,这也就是我们为什么选择用大写字母开头的成员名称。
细心的读者可能已经注意到,其中 Year 名字的成员在编码后变成了 released,还有 Color 成员编码后变成了小写字母开头的 color。这是因为 构体成员 Tag 所导致的。一个构体成员 Tag 是和在编译阶段关联到该成员的 元信息字符串:
Year int `json:"released"`
Color bool `json:"color,omitempty"`
结构体的成员 Tag 可以是任意的字符串面值,但是通常是一系列用空格分 隔的 key:”value”键值对序列;因为值中含义双引号字符,因此成员 Tag 一 般用原生字符串面值的形式书写。json 开头键名对应的值用于控制 encoding/json 包的编码和解码的行为,并且 encoding/…下面其它的包也 遵循这个约成员 Tag 中 json 对应值的第一部分用于指定 JSON 对象的名 字,比如将 Go 语言中的 TotalCount 成员对应到 JSON 中的 total_count 对象。Color 成员的 Tag 还带了一个额外==的 omitempty== 选项,表示当 Go 语言结
构体成员为空或零值时不生成 JSON 对象(这里 false 为零值)。果然, Casablanca 是一个黑白电影,并没有输出 Color 成员。
编码的逆操作是解码,对应将 JSON 数据解码为 Go 语言的数据结构,Go 语言中一般叫unmarshaling,通过json.Unmarshal函数完成。下面的代码 将 JSON 格式的电影数据解码为一个结构体 slice,结构体中只有 Title 成员。 通过定义合适的 Go 语言数据结构,我们可以选择性地解码 JSON 中感兴趣的 成员。当 Unmarshal 函数调用返回,slice 将被只含有 Title 信息值填充, 其它 JSON 成员将被忽略。
var titles []struct{ Title string}
if err:=json.Unmarshal(data,&titles);err!=nil{
log.Fatalf("JSON unmarshaling failed:%s", err)
}
每一次函数调用都必须按照声明顺序为所有参数提供实参(参数值)。在 函数调用时,Go 语言没有默认参数值,也没有任何方法可以通过参数名指定 形参,因此形参和返回值的变量名对于函数调用者而言没有意义。
在函数体中,函数的形参作为局部变量,被初始化为调用者提供的值。函 数的形参和有名返回值作为函数最外层的局部变量,被存储在相同的词法块 中。
实参通过值的方式传递,因此函数的形参是实参的拷贝。对形参进行修改 不会影响实参。但是,如果实参包括引用类型,如指针,slice(切片)、map、 function、channel 等类型,实参可能会由于函数的简介引用被修改。
你可能会偶尔遇到没有函数体的函数声明,这表示该函数不是以 Go 实现 的。这样的声明定义了函数标识符。