GO 基础语法加强1


概要:

  • 设计模式 web、中间件(consul、etcd、tidb)、偏底层(docker、k8s)
  • httpserver、rpc \ grpc、http3(quic)、go-micro、gokit
  • 模板、nginx、gin、gin++

IDE 配置:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1. type 关键字;

# 进入 /Users/go/go2/
go mod init goplus

在这里插入图片描述

  • 文件 /Users/go/go2/src/String/String.go
package String

type String string 	//自己定义的 string

// 返回自定义的 String
func From(str string) (String) {
	// String 强制转化,本质是一样的
	return String(str)
}
  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"goplus/src/String"
)

func main() {
	s := String.From("abc")
	fmt.Println(s)
}

2. 定制的 String、类型方法、int 变 string;

  • 文件 /Users/go/go2/src/String/String.go
package String

import (
	"fmt"
)

type String string 	//自己定义的 string

// 实现类似于类方法的函数
// 返回长度
func (this String) Len() (int) {
	return len(this)
}


// 返回自定义的 String
func From(str string) (String) {
	// String 强制转化,本质是一样的
	return String(str)
}

func FromInt(n int) (String) {
	// 当成 string 转,直接会当成 ASCII 码值
	// 所以调用方法会返回 "{",ASCII 123 对应的符号
	// return String(n)

	// 第一种写法:内置转化方法
	// return String(strconv.Itoa(n))

	// 第二种写法
	return String(fmt.Sprintf("%d", n))

}
  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"goplus/src/String"
)

func main() {
	// s := String.From("abc")
	s := String.FromInt(123)
	fmt.Println(s)
	fmt.Println(s.Len())	//类方法
}

3. 定制的 String:遍历字符串、Each;

  • 文件 /Users/go/go2/src/String/String.go
package String

import (
	"fmt"
)

type String string 	//自己定义的 string

// 实现类似于类方法的函数
// 返回长度
func (this String) Len() (int) {
	return len(this)
}

// !!遍历(函数里的参数是可以传函数的)
func (this String) Each(f func(item string)) {
	for i :=0; i < len(this); i++ {
		// fmt.Println(i, ", ",fmt.Sprintf("%c", this[i]))
		f(fmt.Sprintf("%c", this[i]))

	}
}

// 返回自定义的 String
func From(str string) (String) {
	// String 强制转化,本质是一样的
	return String(str)
}

func FromInt(n int) (String) {
	// 当成 string 转,直接会当成 ASCII 码值
	// 所以调用方法会返回 "{",ASCII 123 对应的符号
	// return String(n)

	// 第一种写法:内置转化方法
	// return String(strconv.Itoa(n))

	// 第二种写法
	return String(fmt.Sprintf("%d", n))

}
  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"goplus/src/String"
)

func main() {
	s := String.From("abcde")
	// s := String.FromInt(123)

	// 遍历
	for i :=0; i < len(s); i++ {
		// 打印出 ASCII 码
		// fmt.Println(i, ", ",s[i])

		// go 没有 char 类型
		// %c 打印 char
		// fmt.Println(i, ", ",fmt.Sprintf("%c", s[i]))
	}

	// 调用遍历
	s.Each(func(item string) {
		fmt.Println(item)	// 返回 abcde
	})

}

4. 定制的 String:遍历字符串(带中文);

  • 文件 /Users/go/go2/src/String/String.go
package String

import (
	"fmt"
)

type String string 	//自己定义的 string

// 实现类似于类方法的函数
// 返回长度
func (this String) Len() (int) {
	return len(this)
}

// 遍历(函数里的参数是可以传函数的)
func (this String) Each(f func(item string)) {
	for i :=0; i < len(this); i++ {
		// fmt.Println(i, ", ",fmt.Sprintf("%c", this[i]))
		f(fmt.Sprintf("%c", this[i]))

	}
}

// !!遍历中文
func (this String) EachC(f func(item string)) {
	for _, c := range this {
		f(fmt.Sprintf("%c", c))

	}
}

// 返回自定义的 String
func From(str string) (String) {
	// String 强制转化,本质是一样的
	return String(str)
}

func FromInt(n int) (String) {
	// 当成 string 转,直接会当成 ASCII 码值
	// 所以调用方法会返回 "{",ASCII 123 对应的符号
	// return String(n)

	// 第一种写法:内置转化方法
	// return String(strconv.Itoa(n))

	// 第二种写法
	return String(fmt.Sprintf("%d", n))

}
  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"goplus/src/String"
)

func main() {
	s := String.From("我123")

	// 返回
	//0   我
	//3   1
	//4   2
	//5   3
	//for index,c := range s {
	//	fmt.Println(index, " ", fmt.Sprintf("%c", c))
	//}

	s.EachC(func(item string) {
		fmt.Println(item)	// 返回 "我123"
	})
}

5. 从字符串中再认识下 byte、rune;

  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"goplus/src/String"
)

func main() {
	s := String.From("我123")

	for i:=0; i<len(s); i++ {
		// fmt.Println(i, "", s[i])	// 打印原始字节
		// fmt.Println(i, "", fmt.Sprintf("%T", s[i]))	// 打印字节的类型(无符号int8)
	}

	// 网络编程和数据传输的时候都是使用"字节" byte
	// 字符串的本质就是字节,虽然表达形式不同

	// uint 类型就是 byte 型,代表 ASCII 码字符集的一个字符
	// 当处理中文、日文、韩文等符合字符时,使用 rune 就是 int 32,也就是 Unicode 字符集(utf8 是编码规则)

	fmt.Println([]byte(s))	// [230 136 145 49 50 51]
	fmt.Println([]int32(s))	// [25105 49 50 51]
	fmt.Println([]rune(s))	// int32 的别名 rune,[25105 49 50 51]
	fmt.Printf("%c", 25105)	// 我

	for _, c :=range s {
		//25105
		//49
		//50
		//51
		fmt.Println(c)	// 字符串遍历,是 unicode 字符集
	}
}

6. 自定义 struct、所谓的构造函数;

在这里插入图片描述

  • 文件 /Users/go/go2/src/Object/User.go
package Object

type User struct {
	Id, Gender int
	Name string
}

func NewUser() (User) {
	return User{}
}
  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"goplus/src/Object"
)

// u 形参参数名
func change(u Object.User) {
	u.Id = 202
}

// 有效,但是一般代码不会这么写,都会用指针
func change2(u Object.User) Object.User {
	u.Id = 202
	return u
}

func main() {
	u := Object.NewUser()
	// fmt.Println(u)	// 默认打印每一项属性的 0 值(初始值):{0 0 }
	//fmt.Printf("%v", u)	// 和上面结果一样
	//fmt.Printf("%+v", u)	// 显示 属性的名称:{Id:0 Gender:0 Name:}

	// 修改属性
	u.Id = 101
	//change(u) 	//   修改无效
	//u = change2(u)	// 修改有效:{Id:202 Gender:0 Name:}{
	//fmt.Printf("%+v", u)

	fmt.Printf("%p", &u)	// 看地址:0xc0000a6020
}

7. 使用指针 struct;

常见的方式是:一律采用指针对 struct 进行初始化

  • 文件 /Users/go/go2/src/Object/User.go
package Object

type User struct {
	Id, Gender int
	Name string
}

func NewUser() (*User) {
	return new (User)
	// return &User{}
}

//func NewUser() (User) {
//	return User{}
//}

  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"goplus/src/Object"
)


func change(u *Object.User) {
	u.Id = 202
	fmt.Printf("%p\n", u)
}


func main() {
	//uu := Object.User{}
	//fmt.Println(uu)	// {0 0 }
	//
	//u := Object.NewUser()
	//fmt.Println(u)	// &{0 0 }
	//
	//
	//var u1 Object.User	// 如此定义, 已经开辟了值
	//var u2 *Object.User	// 定义指针变量,得进行初始化
	//fmt.Println(u1, u2)	// {00 }	<nil>

	u := Object.NewUser()

	change(u)	// 0xc00000c060
	fmt.Printf("%p\n", u)	// 0xc00000c060
	fmt.Println(u)	// &{202 0 }

	// struct 传参尽量使用指针,仅仅是地址的值,不会是 struct 里的 内容
	// go 里面是按值传递,就算传的是指针,不会复制 struct 本身内容,但是会复制地址的值
	// 地址的值对应的地址是不一样的

}

8. 构造函数技巧:任意设置属性值;

  • 文件 /Users/go/go2/src/Object/User.go
package Object

type User struct {
	Id, Gender int
	Name string
}

// 有选择性的对 Id 进行赋值
func NewUser(f func(u *User)) (*User) {
	u := new (User)
	f(u)
	return u
}

// 用来构造上面的 f 函数
//仅仅返回 function 而不是执行结果
func WithUserId(id int) (f func(u *User)) {
	return func(u *User) {
		u.Id = id
	}
}
  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"goplus/src/Object"
)

func main() {
	u := Object.NewUser(
		Object.WithUserId(120),
		)
	fmt.Println(u)	// 	&{120 0 }

}

9. 构造函数技巧:可变参数;

  • 文件 /Users/go/go2/src/Object/User.go
package Object

type User struct {
	Id int
	Name string
	Gender byte
}

// 有选择性的进行赋值(可变参数,参数类型是 function)
func NewUser(fs  ...func(u *User)) (*User) {
	u := new (User)
	for _, f := range fs {
		f(u)
	}

	return u
}
  • 文件 /Users/go/go2/src/Object/UserAttrs.go
package Object

func WithUserId(id int) (f func(u *User)) {
	return func(u *User) {
		u.Id = id
	}
}

func WithUserName(name string) (f func(u *User)) {
	return func(u *User) {
		u.Name = name
	}
}
  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"goplus/src/Object"
)

func main() {
	u := Object.NewUser(
		Object.WithUserId(120),
		Object.WithUserName("hua"),
		)
	fmt.Println(u)

}

10. 构造函数技巧:进一步封装;

  • 文件 /Users/go/go2/src/Object/UserAttrs.go
package Object

// type UserAttrFunc func(u *User)

type UserAttrFunc func(*User)	// 用来设置 User 属性的函数类型,参数可省略

type UserAttrFuncs []UserAttrFunc

// 类方法
//func (this UserAttrFunc) apply (u *User){
//	this(u)
//}

func (this UserAttrFuncs) apply (u *User){
	for _, f := range this {
		f(u)
	}
}

func WithUserId(id int) (UserAttrFunc) {
	return func(u *User) {
		u.Id = id
	}
}

func WithUserName(name string) (UserAttrFunc) {
	return func(u *User) {
		u.Name = name
	}
}
  • 文件 /Users/go/go2/src/Object/User.go
package Object

type User struct {
	Id int
	Name string
	Gender byte
}

// 有选择性的进行赋值(可变参数,参数类型是 function)
func NewUser(fs  ...UserAttrFunc) (*User) {
	u := new (User)
	//for _, f := range fs {
	//	f.apply(u)
	//}

	UserAttrFuncs(fs).apply(u)

	// fmt.Printf("%T", fs)	// 查看类型

	return u
}

11. map强化、基本使用、模拟 User 实体的创建;

在这里插入图片描述

  • 文件 /Users/go/go2/src/Map/User.go
package Map

// 自定义类型

type User map[string]string

func NewUser() (User) {
	// 初始化 map
	return make(map[string]string)
}
  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"goplus/src/Map"
)

// 几个类型: map、chan、slice
func change(u Map.User) {
	u["id"] = "404"
}

func main() {
	//var user map[string]string
	//
	 初始化map
	//user = make(map[string]string)
	//
	//user["id"] = "101"
	//
	//fmt.Println(user)

	u := Map.NewUser()
	u["id"] = "202"
	u["name"] = "hua"

	change(u)	// 可以改值

	//  map 引用类型、传参数传的是所对应地址的值(go都是按值传递)
	fmt.Println(u)

}

12. 设置值、链式调用;

  • 文件 /Users/go/go2/src/Map/User.go
package Map

// 自定义类型

type User map[string]interface{}

func (this User) With(k string, v interface{}) (User){
	this[k] = v
	return this
}

func NewUser() (User) {
	// 初始化 map
	return make(map[string]interface{})
}
  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"goplus/src/Map"
)

func main() {
	u := Map.NewUser()
	//u.With("id", "212")
	//u.With("name", "hua")

	// 链式调用
	u.With("id", 212).
		With("name", "hua")

	fmt.Println(u)
}

13. 遍历 map、按格式打印 map;

  • 文件 /Users/go/go2/src/Map/User.go
package Map

import "fmt"

// 自定义类型

type User map[string]interface{}

func (this User) With(k string, v interface{}) (User){
	this[k] = v
	return this

}

//func (this User) String()  {
//	for k, v := range this {
//		fmt.Printf("%v->%v\n", k, v)
//	}
//}

// 没有 string 方法,有默认的打印值
// 有 string 方法 直接调用
// 并不是每次按顺序打印
func (this User) String() string {
	str := ""
	for k, v := range this {
		str +=fmt.Sprintf("%v->%v\n", k, v)
	}
	return str
}

func NewUser() (User) {
	// 初始化 map
	return make(map[string]interface{})
}
  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"goplus/src/Map"
)

func main() {
	u := Map.NewUser()

	// 链式调用
	u.With("id", 212).
		With("name", "hua")

	//fmt.Println(u)	// map[id:212 name:hua]
	// u.String()	// id->212name->hua

	fmt.Println(u)	// 有定义的string方法,则打印出:id->212name->hua
}

14. 排序 Map Key、Sort 包的初步使用;

  • 文件 /Users/go/go2/src/Map/User.go
package Map

import (
	"fmt"
	"sort"
)

// 自定义类型

type User map[string]interface{}

func (this User) With(k string, v interface{}) (User){
	this[k] = v
	return this

}


func (this User) String() string {
	str := ""
	for index, k := range this.Fields() {
		str +=fmt.Sprintf("%d、%v->%v\n", index+1, k, this[k])
	}
	return str
}

// 返回切片
func (this User) Fields() ([]string) {
	keys := []string{}
	for k, _ := range this{
		keys = append(keys, k)
	}
	// sort.Strings(sort.StringSlice(keys))	// 正排序
	// sort.Strings(keys)	// 正排序
	// sort.Sort(sort.StringSlice(keys))	// 正排序
	sort.Sort(sort.Reverse(sort.StringSlice(keys)))	// 倒叙(全写)
	return keys
	//1、age->27
	//2、gender->male
	//3、id->212
	//4、name->hua
}


func NewUser() (User) {
	// 初始化 map
	return make(map[string]interface{})
}
  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"goplus/src/Map"
)

func main() {
	u := Map.NewUser()

	// 链式调用
	u.With("id", 212).
		With("name", "hua").
		With("gender", "male").
		With("age", 27)

	fmt.Println(u)
}

15. 多个 map 之间的排序方法;

  • 文件 /Users/go/go2/src/Map/User.go
package Map

import "sort"

// 自定义类型

type User map[string]interface{}

func (this User) With(k string, v interface{}) (User){
	this[k] = v
	return this

}


//func (this User) String() string {
//	str := ""
//	for index, k := range this.Fields() {
//		str +=fmt.Sprintf("%d、%v->%v\n", index+1, k, this[k])
//	}
//	return str
//}

// 返回切片
func (this User) Fields() ([]string) {
	keys := []string{}
	for k, _ := range this{
		keys = append(keys, k)
	}
	// sort.Strings(sort.StringSlice(keys))	// 正排序
	// sort.Strings(keys)	// 正排序
	// sort.Sort(sort.StringSlice(keys))	// 正排序
	sort.Sort(sort.Reverse(sort.StringSlice(keys)))	// 倒叙(全写)
	return keys
	//1、age->27
	//2、gender->male
	//3、id->212
	//4、name->hua
}


func NewUser() (User) {
	// 初始化 map
	return make(map[string]interface{})
}
  • 文件 /Users/go/go2/src/main.go
package main

import (
	"fmt"
	"goplus/src/Map"
	"sort"
)

func main() {
	u1 := Map.NewUser()
	u1.With("id", 212).
		With("name", "hua").
		With("age", 33)

	u2 := Map.NewUser()
	u2.With("id", 12).
		With("name", "zhang").
		With("age", 27)

	u3 := Map.NewUser()
	u3.With("id", 121).
		With("name", "wang").
		With("age", 50)

	users := []Map.User{}
	users = append(users, u1, u2, u3)

	sort.Slice(users, func(i, j int) bool {
		age1 := users[i]["age"]. (int)	// 断言,针对 interface
		age2 := users[i]["age"]. (int)
		return age1>age2
	})

	fmt.Println(users)	// [map[age:33 id:212 name:hua] map[age:27 id:12 name:zhang] map[age:50 id:121 name:wang]]
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值