Go标记
Go 程序可以由多个标记组成,可以是关键字,标识符,常量,字符串,符号。如以下 GO 语句由 6 个标记组成:
fmt.Println("Hello, World!")
6 个标记是(每行一个):
- fmt
- .
- Println
- (
- "Hello, World!"
- )
行分隔符
在 Go 程序中,一行代表一个语句结束。每个语句不需要像 C 家族中的其它语言一样以分号 ; 结尾,因为这些工作都将由 Go 编译器自动完成。
如果你打算将多个语句写在同一行,它们则必须使用 ; 人为区分,但在实际开发中我们并不鼓励这种做法。
以下为两个语句:
fmt.Println("Hello, World!") fmt.Println("菜鸟教程:runoob.com")
注释
注释不会被编译,每一个包应该有相关注释。
单行注释是最常见的注释形式,你可以在任何地方使用以 // 开头的单行注释。多行注释也叫块注释,均已以 /* 开头,并以 */ 结尾。如:
// 单行注释 /* Author by 菜鸟教程 我是多行注释 */
标识符
标识符用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母(A~Z和a~z)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字。
以下是有效的标识符:
mahesh kumar abc move_name a_123 myname50 _temp j a23b9 retVal
以下是无效的标识符:
- 1ab(以数字开头)
- case(Go 语言的关键字)
- a+b(运算符是不允许的)
字符串连接
类似java
+
package main import "fmt" func main() { fmt.Println("Google" + "Runoob") }
关键字
下面列举了 Go 代码中会使用到的 25 个关键字或保留字:
Go 语言的空格
在 Go 语言中,空格通常用于分隔标识符、关键字、运算符和表达式,以提高代码的可读性。
Go 语言中变量的声明必须使用空格隔开,如:
var x int const Pi float64 = 3.14159265358979323846
在运算符和操作数之间要使用空格能让程序更易阅读:
无空格:
fruit=apples+oranges;
在变量与运算符间加入空格,程序看起来更加美观,如:
fruit = apples + oranges;
在关键字和表达式之间要使用空格。
例如:
if x > 0 { // do something }
在函数调用时,函数名和左边等号之间要使用空格,参数之间也要使用空格。
例如:
result := add(2, 3)
格式化字符串
Go 语言中使用 fmt.Sprintf 或 fmt.Printf 格式化字符串并赋值给新串:
- Sprintf 根据格式化参数生成格式化的字符串并返回该字符串。
- Printf 根据格式化参数生成格式化的字符串并写入标准输出。
package main import "fmt" func main() { // %d 表示整型数字,%s 表示字符串 var stockCode = 123 var endDate = "2020-12-31" var url = "Code=%d&endDate=%s" var targetUrl = fmt.Sprintf(url, stockCode, endDate) fmt.Println(targetUrl) }
我的idea提示我变量名使用小驼峰, 这样比较适合我一个java coder , to be a better gopher
Go 语言数据类型
在 Go 编程语言中,数据类型用于声明函数和变量。
数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存。
Go 语言按类别有以下几种数据类型:
布尔型
布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true。
数字类型
整型 int 和浮点型 float32、float64,Go 语言支持整型和浮点型数字,并且支持复数,其中位的运算采用补码。
字符串类型:
字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本。
派生类型:
包括:
- (a) 指针类型(Pointer)
- (b) 数组类型
- (c) 结构化类型(struct)
- (d) Channel 类型
- (e) 函数类型
- (f) 切片类型
- (g) 接口类型(interface)
- (h) Map 类型
数字类型
Go 也有基于架构的类型,例如:int、uint 和 uintptr。
1 | uint8无符号 8 位整型 (0 到 255) |
2 | uint16无符号 16 位整型 (0 到 65535) |
3 | uint32无符号 32 位整型 (0 到 4294967295) |
4 | uint64无符号 64 位整型 (0 到 18446744073709551615) |
5 | int8有符号 8 位整型 (-128 到 127) |
6 | int16有符号 16 位整型 (-32768 到 32767) |
7 | int32有符号 32 位整型 (-2147483648 到 2147483647) |
8 | int64有符号 64 位整型 (-9223372036854775808 到 9223372036854775807) |
浮点型
1 | float32IEEE-754 32位浮点型数 |
2 | float64IEEE-754 64位浮点型数 |
3 | complex6432 位实数和虚数 |
4 | complex12864 位实数和虚数 |
其他数字类型
1 | byte类似 uint8 |
2 | rune类似 int32 |
3 | uint32 或 64 位 |
4 | int与 uint 一样大小 |
5 | uintptr无符号整型,用于存放一个指针 |
Go 语言变量
变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念。
变量可以通过变量名访问。
Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。
声明变量的一般形式是使用 var 关键字:
var identifier type
可以一次声明多个变量:
var identifier1, identifier2 type
反射编程
通过反射获取结构的属性
通过反射获取类型
func checkTypeAndValue(op interface{}) { fmt.Printf("type: %T\n", reflect.TypeOf(op)) fmt.Printf("type: %T\n", reflect.TypeOf(op).Kind()) fmt.Printf("value: %T\n", reflect.ValueOf(op)) }
通过反射调用方法
func reflectObj() { op := Student{ Name: "张三", } name := reflect.ValueOf(op).FieldByName("Name") fmt.Printf("name: %v\n", name) if byName, b := reflect.TypeOf(op).FieldByName("Name"); b { fmt.Printf("json format tag : %v \n", byName.Tag.Get("json")) } else { fmt.Printf("reflect no name field\n") } methodByName := reflect.ValueOf(&op).MethodByName("UpdateName") fmt.Printf("methodByName: %v\n", methodByName) reflect.ValueOf(&op).MethodByName("UpdateName").Call([]reflect.Value{reflect.ValueOf("赵四")}) fmt.Printf("new name is %v", reflect.ValueOf(op).FieldByName("Name")) }
在调用方法的位置,一定要用reflect.ValueOf(&op) 取对象内存地形的形式传参,否则会找不到目标方法。暂时还没能理解到底是什么原因。
JSON序列化反序列化
go原生工具
package json import ( "encoding/json" "testing" ) type User struct { Name string `json:"name"` Age int `json:"age"` Gender string `json:"gender"` } func TestJsonSerialize(t *testing.T) { var u = User{ Name: "张三", Age: 18, Gender: "fame", } uNew := new(User) if marshal, err := json.Marshal(u); err == nil { t.Log(string(marshal)) if err := json.Unmarshal(marshal, uNew); err == nil { t.Logf("new User is : %v", uNew) } } }
由于原生工具的方式为反射,效率比较低下,在高并发场景下不适用
easyJSON
go get -u
github.com/mailru/easyjson
Windows 找到不到安装路径, 我发使用easyJson命令,没有管理员权限,无法修改环境变量path
http服务
内置实现
func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { _, err := w.Write([]byte("Hello World")) if err != nil { return } }) err := http.ListenAndServe(":8080", nil) if err != nil { return } }
第三方组件
httprouter