🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
> ### 例子一 ~~~ package demo11 import ( "fmt" "encoding/json" ) type User struct { name string age int } func NewUser(name string, age int) *User { var user *User = &User{name, age} return user } type exam struct { number1 int number2 int number3 int number4 int } type student struct { grade int subject string *people } type people struct { name string age int } type message struct { Id int `json:"user_id",db:"user_id"` Title string `db:"user_title"` Content1 string content2 string //小写私有, 别的包是无法访问的 } func Demo11() { //new(User) 和 &User{} 本质上是一样的,都是返回结构体地址 var user1 *User = new(User) fmt.Printf("%p\n", user1) var user2 *User = &User{} fmt.Printf("%p\n", user2) var user3 User fmt.Printf("%v\n", user3) //结构体里的字段占用一段连续的内存空间 //%p 十六进制表示,前缀 0x var exam *exam = &exam{} fmt.Printf("%p\n", &exam.number1) fmt.Printf("%p\n", &exam.number2) fmt.Printf("%p\n", &exam.number3) fmt.Printf("%p\n", &exam.number4) //结构体没有构造函数, 可以自己实现 //构造函数 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值 var user4 *User = NewUser("张三", 25) fmt.Printf("%v\n", user4) //匿名字段默认采用类型名作为字段名 //结构体嵌套 var student1 student student1.people = &people{ name: "李四", age: 15, } fmt.Printf("%#v \n %#v \n", student1, student1.people) var student2 student //未初始化默认指向空的内存 student2.people = &people{} student2.name = "王五" student2.age = 16 fmt.Printf("%#v \n %#v \n", student2, student2.people) //tag是结构体的原信息, 可以在运行时通过反射的机制读取出来 msg1 := &message{ Id: 1, Title: "标题1", Content1: "内容1", content2: "内容2", } data, _ := json.Marshal(msg1) fmt.Println(string(data)) } ~~~ > ### 例子二 ~~~ package demo12 import ( "fmt" "encoding/json" ) //Go的方法是在函数前面加上一个接受者, 这样编译器就知道这个方法属于哪个类型了 //函数不属于任何类型, 方法属于特定的类型 type User struct { name string age int content string } //可以为当前包定义的类型添加方法 type User2 int //什么时候用值类型/指针类型作为接受者? //需要修改接受者中的值; 接受者是大对象的时候,副本拷贝代价比较大; 通常使用指针类型作为接受者 func (u *User) Msg(name string, age int) { u.name = name u.age = age } func (u User) Say() { fmt.Printf("name:%s-age:%d\n", u.name, u.age) } //匿名函数体与继承 //json在线解析 //json反序列话 type User3 struct { Work string Content string *People } type People struct { Name string Age int } func Demo12() { var user3 = User3{ Work: "student", Content: "Hello World", People: &People{ Name: "张三", Age: 18, }, } fmt.Printf("%+v\r", user3) //字段名要大写, 不然其它包无法访问 data, _ := json.Marshal(user3) fmt.Println(string(data)) //反序列化的 对象 与序列化的对象保持相同类型 var data2 User3 json.Unmarshal(data, &data2) //\r - carriage return, 回车就是输出光标回到本行的开头位置 //\n - new line, 而换行是移动到下一行 /* *** \r _ *** \n ***_ _ *** \n\r ***_ _ */ //不同运行环境对 CR/LF 的解释表达不完全一致(就是不同操作系统,编辑器对\r \n 处理不同), a := 1 fmt.Printf("111-%d \r", a) fmt.Printf("222-%d \r", a) fmt.Printf("333-%d \r", a) } ~~~ > ### 例子三 ~~~ package main import "fmt" type Human interface { Content() } type Teacher struct { Name string TeacherSubject string } type Student struct { Name string Score float32 } func (t *Teacher) Content() { fmt.Printf("Teacher: my name is %s, teachering %s \r\n", t.Name, t.TeacherSubject) } func (s *Student) Content() { fmt.Printf("Student: my name is %s, score %.1f \r\n", s.Name, s.Score) } func SayContent(h Human) { h.Content() } func main() { fmt.Println("Begin Say") //new(Teacher) 和&Teacher{} 本质上是一样的,都是返回结构体地址 t := new(Teacher) t = &Teacher{Name: "张三", TeacherSubject: "计算机"} SayContent(t) s := &Student{Name: "李四", Score: 80.5} SayContent(s) } ~~~