go.mod
module go-app
go 1.20
user/user.go
package user
// Hello 首字母大写为公共方法
func Hello() string {
return "Hello"
}
main.go
package main
import (
"fmt"
"go-app/user"
)
func main() {
str := user.Hello()
fmt.Println(str)
}
声明的变量必须使用,否则报错异常
package main
import (
"fmt"
)
func funA() (string, int) {
// 匿名变量
return "Lee", 12
}
func main() {
// 变量初始化
var name string = "123"
fmt.Println(name) // 123
// 批量变量初始化
var (
realName string = "Lee"
age int = 24
sex string = "难~"
)
fmt.Printf("%v ---> %v ---> %v \n", realName, age, sex) // Lee ---> 24 ---> 难~
// 类型推断
var say = "Hello"
fmt.Println(say) // Hello
// 批量初始化
var a, b, c = 1, 2, 3
fmt.Printf("%v ---> %v ---> %v \n", a, b, c) // 1 ---> 2 ---> 3
// (短变量声明)只能应用于函数内部
x := 4
y := 5
z := 6
fmt.Printf("%v ---> %v ---> %v \n", x, y, z) // 4 ---> 5 ---> 6
// 匿名变量
str, num := funA()
fmt.Println(str, num) // Lee 12
}
基本常量
const HELLO = "Hello Lee!!!"
iota
从0开始,每次调用自动加1const (
count1 = iota
count2 = iota
count3 = iota
)
fmt.Println(count1, count2, count3) // 0 1 2
_
跳过const (
count1 = iota
_
count3 = iota
)
fmt.Println(count1, count3) // 0 2
中间插值
等价于跳过const (
count1 = iota
count2 = 100
count3 = iota
)
fmt.Println(count1, count2, count3) // 0 100 2
package main
import "fmt"
func i() string {
return "I"
}
func main() {
var a = "Lee"
var b = 18
var c = true // 注意:不允许用0或1来表示false或true
var d = 12.5
var e = &d // 取d的地址(指针类型)
var f = [...]int{1, 2, 3} // [...] 省略长度
var g = []int{1, 2, 3} // 动态数组
var h = [4]int{1, 2, 3} // 固定长度数组
var j = `
Hello Lee
` // 字符串字面量,可换行
fmt.Printf("%T \n", a) // string
fmt.Printf("%T \n", b) // int
fmt.Printf("%T \n", c) // bool
fmt.Printf("%T \n", d) // float64
fmt.Printf("%T \n", e) // *float64
fmt.Printf("%T \n", f) // [3]int
fmt.Printf("%T \n", g) // []int
fmt.Printf("%T \n", h) // [4]int
fmt.Printf("%T \n", i) // func() string
fmt.Printf("%T \n", nil) //
fmt.Printf("%v \n", j) // 字符串...
}
package main
import (
"bytes"
"fmt"
"strings"
)
func main() {
// 字符串拼接
a := "Hello"
b := "Lee"
msg1 := fmt.Sprintf("%s %s!!!", a, b)
fmt.Println(msg1) // Hello Lee!!!
msg2 := strings.Join([]string{a, b}, "-")
fmt.Println(msg2) // Hello-Lee
var buffer bytes.Buffer
buffer.WriteString("Hello ")
buffer.WriteString("Lee")
fmt.Println(buffer.String()) // Hello Lee
// 字符串切片
msg3 := "Hello Lee, My name is WangDeFa!!!"
fmt.Println(msg3[1]) // 101 获取字符串索引为1的原始字节
fmt.Println(msg3[2:7]) // llo L
fmt.Println(msg3[3:]) // lo Lee, My name is WangDeFa!!!
fmt.Println(msg3[:4]) // Hell
// 字符串分割
msg4 := "Hello Lee, My name is WangDeFa!!!"
fmt.Println(strings.Split(msg4, "e")) // [H llo L , My nam is WangD Fa!!!]
// 是否包含某个字符串
msg5 := "Hello Lee!!!"
fmt.Println(strings.Contains(msg5, "ee")) // true
fmt.Println(strings.Contains(msg5, "ele")) // false
// 转换为大小写
msg6 := "Hello Lee!!!"
fmt.Println(strings.ToUpper(msg6)) // HELLO LEE!!!
fmt.Println(strings.ToLower(msg6)) // hello lee!!!
// 判断开头或结尾是否有指定字符串
msg7 := "Hello Lee!!!"
fmt.Println(strings.HasPrefix(msg7, "Hello")) // true
fmt.Println(strings.HasSuffix(msg7, "Lee")) // false
fmt.Println(strings.HasSuffix(msg7, "Lee!!!")) // true
// 查询字符串索引值
msg8 := "Hello Lee!!!"
fmt.Println(strings.Index(msg8, "ee")) // 7
fmt.Println(strings.Index(msg8, "e")) // 1
}
++
--
运算符
++
--
是单独的运算符,不能添加到表达式中
package main
import "fmt"
func main() {
a := 123
a++
fmt.Println(a) // 124
a--
fmt.Println(a) // 123
}
错误形式
a := 123
++a // Error: '++' unexpected
--a // Error: '--' unexpected
123 + a++ // Error: Cannot assign to 123 +
||
&&
!
只能应用于bool
值之间
for ... := range ...
package main
import "fmt"
func main() {
list := [...]any{"Lee", 25, "☹️"}
for i, d := range list {
fmt.Println(i, d) // 0 Lee 1 25 2 ☹️
}
}
switch
和其他语言不同,不需要添加
break
package main
import "fmt"
func main() {
var num int
fmt.Scan(&num)
switch num {
case 1:
fmt.Println(num)
case 2:
fmt.Println(num)
case 3:
fmt.Println(num)
case 4, 5, 6:
fmt.Println(num)
default:
fmt.Println("空")
}
}
case
表达式
package main
import "fmt"
func main() {
var score int
fmt.Scan(&score)
switch {
case score >= 90 && score <= 120:
fmt.Println("优秀")
case score > 120:
fmt.Println("作弊")
default:
fmt.Println("一般")
}
}
实现类似其他语言不添加break
的效果(fallthrough
)
package main
import "fmt"
func main() {
var num int
fmt.Scan(&num) // 1 --> 一 二 三 2 --> 二 三
switch num {
case 1:
fmt.Println("一")
fallthrough
case 2:
fmt.Println("二")
fallthrough
case 3:
fmt.Println("三")
case 4, 5, 6:
fmt.Println("四五六")
default:
fmt.Println("空")
}
}
package main
import "fmt"
func main() {
count := 0
for {
count++
fmt.Println(count) // ...
}
}
跳出循环
package main
import "fmt"
func main() {
count := 0
for {
count++
fmt.Println(count) // 1 - 100
if count > 99 {
break
}
}
}
package main
import "fmt"
func main() {
count := 0
for {
count++
fmt.Println(count) // 1 - 11
if count > 10 {
goto endPrint
}
}
endPrint: // 标签
fmt.Println("结束")
}
package main
import "fmt"
func main() {
list := []any{1, true, "Lee"}
// 增
res1 := append(list, "啥?")
fmt.Println(list) // [1 true Lee]
fmt.Println(res1) // [1 true Lee 啥?]
res2 := append(list, res1...)
fmt.Println(list) // [1 true Lee]
fmt.Println(res2) // [1 true Lee 1 true Lee 啥?]
// 改
list[1] = "假"
fmt.Println(list) // [1 假 Lee]
// 查
fmt.Println(list[2]) // Lee
fmt.Println(list[1:]) // [假 Lee]
// 浅拷贝
res3 := list
res3[0] = 123
fmt.Println(list) // [123 假 Lee]
fmt.Println(res3) // [123 假 Lee]
// 深克隆
res4 := make([]any, len(list))
copy(res4, list)
res4[1] = 456
fmt.Println(list) // [123 假 Lee]
fmt.Println(res4) // [123 456 Lee]
// 删 - 删除索引1
list = append(list[:1], list[2])
fmt.Println(list) // [123 Lee]
}
map
的CURDCURD
package main
import "fmt"
func main() {
//data := make(map[string]any)
//data["name"] = "Lee"
data := map[string]any{
"name": "Lee",
}
// 改
data["name"] = "Tom"
// 增
data["age"] = 18
data["height"] = 171
// 删
delete(data, "height")
// 查
fmt.Printf("%v ---> %v ---> %v", data["name"], data["age"], data["height"]) // Tom ---> 18 --->
}
拷贝
package main
import "fmt"
func main() {
data1 := map[string]any{
"name": "Lee",
"age": 18,
"height": 171,
}
// 浅拷贝
data2 := data1
data2["name"] = "Tom"
fmt.Printf("%v ---> %v ---> %v\n", data1["name"], data1["age"], data1["height"]) // Tom ---> 18 ---> 171
fmt.Printf("%v ---> %v ---> %v\n", data2["name"], data2["age"], data2["height"]) // Tom ---> 18 ---> 171
// 深克隆
data3 := make(map[string]any)
for key, value := range data1 {
data3[key] = value
}
data3["name"] = "Lucy"
fmt.Printf("%v ---> %v ---> %v\n", data1["name"], data1["age"], data1["height"]) // Tom ---> 18 ---> 171
fmt.Printf("%v ---> %v ---> %v\n", data3["name"], data3["age"], data3["height"]) // Lucy ---> 18 ---> 171
}
判断字段是否存在
package main
import "fmt"
func main() {
data := map[string]any{
"name": "Lee",
"age": 18,
"height": 171,
}
height, hasHeight := data["height"]
fmt.Println(height, hasHeight) // 171 true
like, hasLike := data["like"]
fmt.Println(like, hasLike) // false
}
基本函数
package main
import "fmt"
func sum1(a int, b int) (res int) {
res = a + b
return res
}
func sum2(a int, b int) int {
res := a + b
return res
}
func sum3(a int, b int) (int, int, int) {
res := a + b
return a, b, res
}
func sum4(a int, b int, c ...int) int {
res := a + b
for _, v := range c {
res += v
}
return res
}
func main() {
fmt.Println(sum1(1, 1)) // 2
fmt.Println(sum2(1, 1)) // 2
fmt.Println(sum3(1, 1)) // 1 1 2
a, b, c := sum3(1, 1)
fmt.Println(a, b, c) // 1 1 2
fmt.Println(sum4(1, 2, 3, 4, 5)) // 15
}
函数类型
package main
import "fmt"
type demo func(int, int) int
func sum(a int, b int) int {
return a + b
}
func max(a int, b int) int {
if a > b {
return a
} else {
return b
}
}
func main() {
var d demo
d = sum
s := d(1, 2)
fmt.Println(s) // 3
d = max
m := d(1, 2)
fmt.Println(m) // 2
}
回调函数
package main
import "fmt"
func sayHello(name string, callback func(string)) {
fmt.Printf("%v: Hello!\n", name)
name = "Tom"
if callback != nil {
callback(name)
}
}
func sayHi(name string) {
fmt.Printf("%v: Hi!\n", name)
}
func main() {
sayHello("Lee", sayHi) // Lee: Hello! Tom: Hi!
}
匿名函数
package main
import "fmt"
func sayHello(name string, callback func(string)) {
fmt.Printf("%v: Hello!\n", name)
name = "Tom"
if callback != nil {
callback(name)
}
}
func main() {
sayHello("Lee", func(name string) {
fmt.Printf("%v: Hi!\n", name)
}) // Lee: Hello! Tom: Hi!
}
立即执行函数
package main
import "fmt"
func main() {
name := func(name string) string {
return name
}("Lee")
fmt.Println(name) // Lee
}
闭包
package main
import "fmt"
func say() func(string) string {
msg := "Hi, "
return func(s string) string {
msg += s
return msg
}
}
func main() {
str := say()
fmt.Println(str("Lee")) // Hi, Lee
fmt.Println(str("-Tom.")) // Hi, Lee-Tom.
}
递归
package main
import "fmt"
func fun(n int) int {
if n == 0 {
return 1
}
return n * fun(n-1)
}
func main() {
fmt.Println(fun(3)) // 6
}
defer
先定义的后输出
package main
import "fmt"
func main() {
fmt.Println(1)
fmt.Println(2)
fmt.Println(3)
defer fmt.Println(4)
defer fmt.Println(5)
defer fmt.Println(6)
defer fmt.Println(7)
fmt.Println(8)
fmt.Println(9)
fmt.Println(0)
// 结果:123 890 7654
}
init
初始化函数执行顺序
变量函数 ---> init函数(按从上到下) ---> main函数
package main
import "fmt"
func init() {
fmt.Println("init1")
}
var data = func() any {
fmt.Println("num")
return nil
}()
func init() {
fmt.Println("init2")
}
func main() {
fmt.Println("main")
}
func init() {
fmt.Println("init3")
}
// 结果: num init1 init2 init3 main
package main
import "fmt"
func main() {
var a = 123
var b *int // int类型的指针变量
// 打印变量值
fmt.Println(b) //
// 打印变量地址
fmt.Println(&a) // 0xc0000ac008
fmt.Println(&b) // 0xc0000a6018
b = &a
// 打印变量地址
fmt.Println(b) // 0xc0000ac008
// 打印变量值
fmt.Println(*b) // 123
}
指向数组的指针
package main
import "fmt"
func main() {
var a = []int{1, 2, 3}
var b [3]*int
// 打印变量值
fmt.Println(b) // [ ]
// 打印变量地址
fmt.Println(&a) // &[1 2 3]
fmt.Println(&a[0], &a[1], &a[2]) // 0xc00001e0d8 0xc00001e0e0 0xc00001e0e8
fmt.Println(&b) // &[ ]
fmt.Println(&b[0], &b[1], &b[2]) // 0xc000010048 0xc000010050 0xc000010058
for i := range a {
b[i] = &a[i]
fmt.Println(b[i]) // 0xc00001e0d8 0xc00001e0e0 0xc00001e0e8
fmt.Println(*b[i]) // 1 2 3
}
}
类型定义
与 类型别名
package main
import "fmt"
// NewInt 自定义类型
type NewInt int
// NewBool 类型别名
type NewBool = bool
func main() {
var a NewInt
fmt.Println(a) // 0
var b NewBool
fmt.Println(b) // false
}
package main
import "fmt"
type UserInfo struct {
name string
age int
height float64
}
func main() {
var info UserInfo
info.name = "Lee"
info.age = 18
info.height = 171
fmt.Println(info) // {Lee 18 171}
}
匿名结构体
package main
import "fmt"
func main() {
var info struct {
name string
age int
height float64
}
info.name = "Lee"
info.age = 18
info.height = 171
fmt.Println(info) // {Lee 18 171}
}
结构体赋值
package main
import "fmt"
type UserInfo struct {
name string
age, height int
}
func main() {
var info UserInfo
// 方式1
info.name = "Lee"
info.age = 18
info.height = 171
// 方式2
info = UserInfo{
"Lee", 18, 171,
}
// 方式3
info = UserInfo{
name: "Lee",
height: 171,
}
fmt.Println(info) // {Lee 18 171}
}
结构体的指针
package main
import "fmt"
type UserInfo struct {
name string
age, height int
}
func main() {
var lee *UserInfo
fmt.Println(lee) //
fmt.Println(&lee) // 0xc000012028
var tom = UserInfo{
name: "Lee",
age: 18,
height: 171,
}
lee = &tom
fmt.Println(lee) // &{Lee 18 171}
fmt.Println(&lee) // 0xc000012028
fmt.Println(*lee) // {Lee 18 171}
}
package main
import "fmt"
type UserInfo struct {
name string
age, height int
}
func main() {
// 初始化结构体的指针
var lee = new(UserInfo)
fmt.Println(lee) // &{ 0 0}
fmt.Println(&lee) // 0xc000012028
var tom = UserInfo{
name: "Lee",
age: 18,
height: 171,
}
lee = &tom
fmt.Println(lee) // &{Lee 18 171}
fmt.Println(&lee) // 0xc000012028
fmt.Println(*lee) // {Lee 18 171}
}
结构体的嵌套
package main
import "fmt"
type UserInfo struct {
name string
age, height int
}
type Person struct {
userInfo UserInfo
msg string
}
func main() {
var tom = Person{
userInfo: UserInfo{
name: "Lee",
age: 18,
height: 171,
},
msg: "Hi",
}
fmt.Println(tom) // {{Lee 18 171} Hi}
}
结构体作为参数
package main
import "fmt"
type UserInfo struct {
name string
age, height int
}
type Person struct {
userInfo UserInfo
msg string
}
func say1(person Person) {
person.msg = "Hello"
person.userInfo.name = "Tom"
fmt.Println(person.msg, person.userInfo.name)
}
func say2(person *Person) {
person.msg = "Hello"
person.userInfo.name = "Tom"
fmt.Println(person.msg, person.userInfo.name)
}
func main() {
var person1 = Person{
userInfo: UserInfo{
name: "Lee",
age: 18,
height: 171,
},
msg: "Hi",
}
say1(person1) // Hello Tom
fmt.Println(person1.msg) // Hi
fmt.Println(person1.userInfo.name) // Lee
var person2 = Person{
userInfo: UserInfo{
name: "Lee",
age: 18,
height: 171,
},
msg: "Hi",
}
say2(&person2) // Hello Tom
fmt.Println(person2.msg) // Hello
fmt.Println(person2.userInfo.name) // Tom
}
方法的接收者是结构体,包含值类型和引用类型时,那么值类型被复制,引用类型不被复制而是引用
package main
import "fmt"
type UserInfo struct {
name string
age, height int
likes []string
}
// info为接收者用于接收
func (info UserInfo) say() {
info.age = 20
info.likes[2] = "play"
fmt.Println(info)
}
func main() {
var userInfo = UserInfo{
name: "Lee",
age: 18,
height: 171,
likes: []string{"吃", "喝", "玩", "乐"},
}
userInfo.say() // {Lee 20 171 [吃 喝 play 乐]} 注意值类型和引用类型的区别
fmt.Println(userInfo) // {Lee 18 171 [吃 喝 play 乐]} 注意值类型和引用类型的区别
}
方法的接收者是指针类型结构体时,那么不被复制而是引用
package main
import "fmt"
type UserInfo struct {
name string
age, height int
likes []string
}
// info为接收者用于接收
func (info *UserInfo) say() {
info.age = 20
info.likes[2] = "play"
fmt.Println(*info)
}
func main() {
var userInfo = UserInfo{
name: "Lee",
age: 18,
height: 171,
likes: []string{"吃", "喝", "玩", "乐"},
}
userInfo.say() // {Lee 20 171 [吃 喝 play 乐]} 注意值类型和引用类型的区别
fmt.Println(userInfo) // {Lee 20 171 [吃 喝 play 乐]} 注意值类型和引用类型的区别
}
接口内的方法必须定义,否则报错
package main
import "fmt"
// Sayer 说接口
type Sayer interface {
say(msg string)
}
// Mover 移动接口
type Mover interface {
move(start int, end int) (name string, distance int)
}
// Animaler 动物接口
type Animaler interface {
Sayer
Mover
}
// Lee 结构体,存放姓名
type Lee struct {
name string
}
func (lee Lee) say(msg string) {
fmt.Println(msg + lee.name)
}
func (lee Lee) move(start int, end int) (name string, distance int) {
distance = end - start
return lee.name, distance
}
func main() {
var lee Animaler
lee = Lee{name: "Lee"}
lee.say("Hi,")
name, distance := lee.move(0, 10)
fmt.Println(name, distance)
}
OCP
: “开-闭”原则
package main
import "fmt"
type Animaler interface {
eat()
sleep()
}
type Person struct {
name string
}
func (person Person) eat() {
fmt.Println(person.name + ",吃...")
}
func (person Person) sleep() {
fmt.Println(person.name + ",睡...")
}
func funA(animal Animaler) {
animal.eat()
animal.sleep()
}
func (person Person) funB(animal Animaler) {
animal.eat()
animal.sleep()
}
func main() {
var animal Animaler = Person{name: "Dog"}
animal.eat() // Dog,吃...
animal.sleep() // Dog,睡...
funA(animal) // Dog,吃... Dog,睡...
var lee Animaler = Person{name: "Lee"}
var tom Animaler = Person{name: "Tom"}
person := Person{}
person.funB(lee) // Lee,吃... Lee,睡...
person.funB(tom) // Tom,吃... Tom,睡...
}
结构体嵌套来实现继承
继承自User
的UserInfo
结构体
package main
import "fmt"
// User 父结构体
type User struct {
say func(msg string)
sleep func()
}
// UserInfo 子结构体
type UserInfo struct {
name string
age int
height float64
User
}
func main() {
lee := UserInfo{
name: "Lee",
age: 18,
height: 171.123,
User: User{
say: func(msg string) {
fmt.Println(msg)
},
sleep: func() {
fmt.Println("sleep...")
},
},
}
fmt.Println(lee) // {Lee 18 171.123 {0x102f8f610 0x102f8f690}}
lee.say("Hi," + lee.name) // Hi,Lee
lee.User.say("Hi," + lee.name) // Hi,Lee
lee.User.sleep() // sleep...
lee.sleep() // sleep...
}
package main
import "fmt"
type UserInfo struct {
name string
age int
height float64
}
// initUserInfo 构造函数
func initUserInfo(name string, age int, height float64) *UserInfo {
return &UserInfo{name: name, age: age, height: height}
}
func main() {
info := UserInfo{
name: "Lee",
age: 18,
height: 171.123,
}
person := initUserInfo(info.name, info.age, info.height)
fmt.Println(info) // {Lee 18 171.123}
fmt.Println(person) // &{Lee 18 171.123}
person.name = "Tom"
fmt.Println(info) // {Lee 18 171.123}
fmt.Println(person) // &{Tom 18 171.123}
}