一、使用方式

方式3和方式4返回的是:结构体指针,编译器底层对 p.Name 做了转化 *(p).Name,方便程序员使用。

type Person struct {
Name string
Age int
} func main() {
// 方式1
var p Person
fmt.Println(p) // { 0}
var p1 = Person{}
p1.Name = "a"
p1.Age = 1
fmt.Println(p1) // {a 1} // 方式2
var p2 = Person{"b", 2}
var p3 = Person{
Name: "b",
Age: 2,
}
p4 := Person{"b", 2}
p5 := Person{
Name: "b",
Age: 2,
}
fmt.Println(p2, p3, p4, p5) // {b 2} {b 2} {b 2} {b 2} // 方式3
var p6 = new(Person) // var p6 *Person = new(Person)
/*
go的设计者,为了程序员的使用方便,底层会对 p6.Name = "c"进行处理,
相当于*(p6).Name = "c"
*/
p6.Name = "c" // *(p6).Name = "c"
p6.Age = 3 // *(p6).Age = 3
fmt.Println(p6) // &{c 3}
fmt.Println(*p6) // {c 3} // 方式4(同方式3)
var p7 = &Person{}
p7.Name = "d"
p7.Age = 4
fmt.Println(p7, *p7) // &{d 4} {d 4} var p8 = &Person{"e", 5}
fmt.Println(p8, *p8) // &{e 5} {e 5} p9 := &Person{}
p9.Name = "f"
p9.Age = 6
fmt.Println(p9, *p9) // &{f 6} {f 6} p10 := &Person{"g", 7}
fmt.Println(p10, *p10) // &{g 7} {g 7}
}

二、结构体中的指针、slice、map的默认值都是nil,即还没分配空间

type Person struct {
Name string
Age int
Score [3]float64
ptr *int
s []int
m map[string]string
} func main() {
var p Person
fmt.Println(p) // { 0 [0 0 0] <nil> [] map[]}
if p.ptr == nil {
fmt.Println("true") // true
}
if p.s == nil {
fmt.Println("true") // true
}
if p.m == nil {
fmt.Println("true") // true
}
// 使用slice和map时,一定要make!!!
p.s = make([]int, 2)
p.s[0] = 88
fmt.Println(p.s) // [88 0]
p.m = make(map[string]string, 2)
p.m["key"] = "value"
fmt.Println(p.m) // map[key:value]
}

三、结构体的tag

struct的每个字段上,可以写上一个tag,该tag可以通过反射机制获取,常见的使用场景就是序列化和反序列化。

package main

import (
"encoding/json"
"fmt"
) type Person struct{
Name string `json:"name"` // `json:"name"`就是结构体tag
Age int // `json:"age"` ,没有写tag,序列化后则为大写字母,如果字段为小写,其他包又不可见
} func main() {
person := Person{"佩奇", 18}
jsonStr, err := json.Marshal(person)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(string(jsonStr)) // {"name":"佩奇","Age":18}
}
}

四、其他

结构体的所有字段在内存中是连续的。

type Student struct {
A int
B int
C int
} func main() {
s := Student{1, 20, 300}
fmt.Println(&s.A) // 0xc00000e3a0
fmt.Println(&s.B) // 0xc00000e3a8
fmt.Println(&s.C) // 0xc00000e3b0
}

结构体是用户单独定义的类型,和其他类型进行转换时需要有完全相同的字段(名字、个数、类型)。

type A struct {
Name string
} type B struct {
Name string
} type C A // 结构体进行type重新定义(相当于取别名) func main() {
var a A
var b B
a = A(b) // 可以强转,但有前提
var c C
c = C(a) // 可以强转
fmt.Println(a, b, c)
}

最新文章

  1. JavaScript 字符串实用常操纪要
  2. Unity3d使用高通Vuforia发布IOS工程不支持64位的一些解决办法
  3. TDR分辨率
  4. 关于js中闭包的理解
  5. 利用nodejs实现登录并转码视频(原创)
  6. 把Java生成的RSA公钥、私钥转换成.NET使用的XML格式
  7. OC中UITabBarController控制器
  8. ASP------ActioinResult之多种返回值
  9. ring0
  10. Codeforces 479E. Riding in a Lift (dp + 前缀和优化)
  11. VBS基础篇 - Err对象
  12. LBP特征提取实现
  13. COJ 0200 Fibonacci
  14. C语言--流程控制
  15. 用Jquery做一个时间日期选择器
  16. Android下NDK开发环境搭建
  17. 第一章 初识 MyBatis
  18. noj 算法 八数码问题
  19. linux下的~/
  20. vi十六进制编辑

热门文章

  1. Jquery 之deferred
  2. Luogu P1233 木棍加工 【贪心/LIS】
  3. CodeForces 923C Perfect Security
  4. 2017 JUST Programming Contest 3.0 H. Eyad and Math
  5. JSP页面自动刷新
  6. Spring------IOC&amp;DI
  7. java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to
  8. WP7 开发资料
  9. 安卓(Android )软键盘的控制(显示和隐藏)
  10. install nginx error