> ### 例子一
~~~
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)
}
~~~
- 第一序 入门教程(一)
- 1.1环境配置
- 1.1 环境配置(补充:Linux下安装)
- 1.1 环境配置(补充:线上部署)
- 1.2 开发工具GoLand
- 1.3 准备工作
- 1.4 第一个应用程序 Hello World
- 1.4 补充 go get github 超时
- 第二序 入门教程(二)
- 2.1 语法结构
- 2.2 常量, 变量
- 2.2.1 命名规则
- 2.2.2 变量
- 2.2.2 变量(补充:类型推断的好处)
- 2.2.2 变量(补充:泛型)
- 2.2.3 常量
- 2.2.4 iota
- 2.2.5 Unicode字符编码
- 2.2.6 GBK 转 UTF8
- 2.3 条件语句
- 2.3.1 判断语句 if
- 2.3.2 选择语句 switch
- 2.3.3 循环语句 for
- 2.3.4 遍历 range
- 2.3.5 跳转语句 goto, break, continue
- 2.3.6 for 和 for range区别
- 2.4 数组, 切片, 集合, 通道
- 2.4.1 make, len, cap, new, nil
- 2.4.1 make, len, cap, new, nil (补充:nil)
- 2.4.2 数组 array
- 2.4.3.1 切片 slice - 1
- 2.4.3.2 切片 slice - 2
- 2.4.3.3 slice list ring
- 2.4.4 集合 map
- 2.4.5 goroutine
- 2.4.6 channel
- 2.5 函数, 结构, 方法, 接口
- 2.5.1 函数 function
- 2.5.2 结构 struct
- 2.5.3 方法 method
- 2.5.4 接口 interface
- 2.5.5 Go是面向对象的语言吗?
- 2.5.6 json序列化和反序列化
- 2.5.7 T和指针T
- 2.6 defer, panic, recover
- 2.6.1 defer
- 2.6.2 painc, recover
- 2.7 指针
- 2.7 指针(补充: 可寻址和不可寻址)
- 2.8 反射
- 第三序 相关阅读
- 3.1 相关阅读1
- 3.2 相关阅读2
- 3.3 相关阅读3
- 第四序 性能分析和调试工具
- 4.1 pprof工具介绍
- 4.2 CPU信息采集
- 4.3 Heap信息采集
- 4.4 Http信息采集
- 4.5 单元测试(功能测试)
- 4.6 基准测试(压力测试/性能测试)
- 4.7 示例测试(example)
- 4.8 gdb调试
- 第五序 网络编程
- 5.1 http请求和响应
- 5.2 socket
- 5.2.1 概念
- 5.2.2 服务端
- 5.2.3 客户端
- 5.3 WebSocket
- 5.3.1 第一版
- 5.3.1.1 服务端
- 5.3.1.2 客户端
- 5.3.1.3 相关阅读
- 5.3.2 服务端
- 5.3.3 客户端
- 5.3.4 nginx配置
- 5.3.5 修改版
- 5.3.5.1 草稿 - 1
- 5.3.5.2 草稿 - 2
- 5.3.5.3 草稿 - 3
- 5.3.5.4 服务端
- 5.3.5.5 客户端
- 5.4 打印客户端头部信息
- 第六序 算法
- 6.1 查找
- 6.1.1 二分查找
- 6.2 排序
- 6.2.1 交换排序 - 冒泡排序
- 6.2.2 插入排序 - 直接插入排序
- 6.2.3 插入排序 - 希尔排序
- 6.2.4 交换排序 - 快速排序
- 6.3 算法求解应用
- 第七序 微服务
- 7.1 相关阅读
- 7.2 gRPC
- 7.2.1 准备工作
- 7.2.2 编译.proto文件
- 7.2.3 gRPC服务端
- 7.2.4 gRPC客户端
- 7.3 micro/micro
- 7.3.1 服务发现
- 7.3.2 安装consul
- 7.3.3 准备工作
- 7.3.4 服务端
- 7.3.5 客户端
- 7.3.6 默认的服务发现
- 7.3.7 文档阅读
- 7.4 protobuf序列化
- 第八序 Web
- 8.1 视图模板
- 8.1.1 main.go
- 8.1.2 login.html
- 8.2 原生留言板
- 8.2.1 原生sql
- 8.2.1.1 main.go
- 8.2.1.2 view
- 8.2.1.2.1 index.html
- 8.2.1.2.2 create.html
- 8.2.2 sqlx
- 8.3 Gin框架
- 第九序 数据库
- 9.0 资料收集
- 9.1 Redis数据库 (gomodule/redigo)
- 9.1.1 介绍
- 9.1.2 消息队列
- 9.2 Redis数据库(go-redis/redis)
- 第十序 日记
- 10.1 SimplePanic
- 10.2 第一版日记库
- 10.2.1 winnielog
- 10.2.2 使用
- 第十一序 中间键
- 11.0 资料收集
- 11.1 NSQ
- 11.2 zookeeper
- 11.3 kafka
- 第十二序 加密
- 12.1 Token
- 12.2 SHA1
- 2.3 RSA + AES
- 第十三序 分布式锁
- 第十四序 标准库练习
- container/list
- 链表
- container/ring
- 环形链表
- context
- flag (获取命令行参数)
- io
- strconv
- sync
- 为什么需要锁?
- 互斥锁
- 读写锁
- 条件变量
- 计数器
- 并发安全字典
- 自制并发安全字典
- 官方并发安全字典
- 连接池
- sync/atomic
- 原子操作
- 第十五序 其它内容
- 文件读写
- 工作池
- 第十六序 相关阅读