go |struct embedding、generics、goroutine

go 的结构内嵌
注意点,有点像js

func main() {

	fmt.Println("hello zhangbuda...")

	// 这个内嵌 和 js 有点像
	co := container{
		base: base{
			num: 22,
		},
		str: "zhangdbau hahahahah ",
	}
	fmt.Println("co: ", co)
	/*
		在 Go 语言中,如果一个类型嵌入了另一个类型,那么嵌入类型的方法就会被自动提升到外部类型,这就意味着你可以直接在外部类型上调用嵌入类型的方法。

		假设 co 是一个结构体,它嵌入了 base 类型,而 base 类型有一个 describe 方法。那么你可以直接在 co 上调用 describe 方法,就像这样:co.describe()。这个调用会自动转发到 base.describe 方法。

		所以,co.describe() 和 co.base.describe() 的结果是一致的,因为它们实际上调用的是同一个方法。

		但是,如果 co 自己也定义了一个 describe 方法,那么 co.describe() 就会调用 co 的 describe 方法,而不是 base.describe 方法。这是因为 Go 语言会优先调用最近的方法,而不是最匹配的方法。
	*/
	fmt.Println("co.describe: ", co.describe())
	fmt.Println("co.base.describe: ", co.base.describe())

	fmt.Println("co.base.num", co.base.num)
	fmt.Println("co.str: ", co.str)
}

type base struct {
	num int
}

func (b base) describe() string {
	//	%v 格式化字符串
	//  %v 会根据值的类型输出对应的值
	return fmt.Sprintf("base with num=%v", b.num)

}

type container struct {
	base
	str string
}
co:  {{22} zhangdbau hahahahah }
co.describe:  base with num=22
co.base.describe:  base with num=22
co.base.num 22
co.str:  zhangdbau hahahahah 

范型 是重点

package main

import (
	"fmt"
)

func main() {

	// 范型
	// 	在 Go 语言中,如果一个类型嵌入了另一个类型,那么嵌入类型的方法就会被自动提升到外部类型,这就意味着你可以直接在外部类型上调用嵌入类型的方法。

	var m = map[int]string{1: "2", 2: "4", 4: "8"}
	fmt.Println("map: ", m)

	fmt.Println("keys: ", MapKeys(m))
	//隐式类型转换
	s1 := MapKeys(m)
	//显式类型转换
	s := MapKeys[string, string](map[string]string{"11": "111", "22": "222", "33": "333"})
	s2 := MapKeys[int, string](m)
	fmt.Println("s1: ", s1, "\ns: ", s, "\ns2: ", s2)

	lst := List[int]{}
	lst.push(10)
	lst.push(13)
	lst.push(23)
	fmt.Println("list: GetAll:", lst.GetAll())
}

/*
	K comparable 表示 K 必须是一个可比较的类型。这是因为在 Go 语言中,map 的键必须是可比较的。
	这样,Go 语言才能正确地查找和比较 map 中的键
*/
func MapKeys[K comparable, V any](m map[K]V) []K {
	r := make([]K, 0, len(m))

	for k := range m {
		r = append(r, k)
	}
	return r
}

// 范型	链表元素
type element[T any] struct {
	next *element[T]
	val  T
}

// 链表结构 包含 头和尾
type List[T any] struct {
	head, tail *element[T]
}

func (lst *List[T]) push(v T) {
	if lst.tail == nil {
		//最开始初始化 链表 头部和尾部都为空
		lst.head = &element[T]{val: v}
		lst.tail = lst.head
	} else {
		// 当链表不为空时,便开始把所有元素一次插入尾部,并更新尾部
		lst.tail.next = &element[T]{val: v}
		lst.tail = lst.tail.next
	}
}

func (lst *List[T]) GetAll() []T {
	// 定义一个空的切片
	var elemes []T
	for e := lst.head; e != nil; e = e.next {
		elemes = append(elemes, e.val)
	}
	return elemes
}

/*
	再次补充 切片知识
	在 Go 语言中,切片(Slice)是对数组的抽象。
	Go 数组的长度不可改变,在特定的场景中这样的集合就不太适用。
	Go 中提供了一种灵活,功能强大的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
	切片是一种方便、灵活且强大的包装器,使得对数组操作更加方便。
	例如: var number []int
		  var str []string
*/

map:  map[1:2 2:4 4:8]
keys:  [1 2 4]
s1:  [1 2 4] 
s:  [11 22 33] 
s2:  [1 2 4]
list: GetAll: [10 13 23]
package main

import (
	"fmt"
	"time"
)

func f(from string) {
	for i := 0; i < 3; i++ {
		fmt.Println(from, ":", i)
	}
}

func main() {

	f("direct-->")

	go f("goroutine-->start")

	go func(msg string) {
		fmt.Println(msg)
	}("going--->")

	time.Sleep(time.Second)
	fmt.Println("done--->end")
}

#  运行结果
direct--> : 0
direct--> : 1
direct--> : 2
going--->
goroutine-->start : 0
goroutine-->start : 1
goroutine-->start : 2
done--->end

go 的并发 还挺方便的

func hello(i int) {
	defer wg.Done()
	fmt.Println("hello", i)
}

// sync.WaitGroup 是Go 的一个同步原语,常常用于等待一组goroutine 完成
var wg sync.WaitGroup

func main() {

	//go f("hello world")

	// fmt.Println("\n===>main function===<\n")
	// time.Sleep(time.Second)

	for i := 1; i <= 10; i++ {
		wg.Add(1)
		go hello(i)
	}
	wg.Wait()
}
#运行结果
hello 10
hello 1
hello 2
hello 3
hello 4
hello 5
hello 6
hello 7
hello 8
hello 9

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-28 05:28:10       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-28 05:28:10       101 阅读
  3. 在Django里面运行非项目文件

    2024-03-28 05:28:10       82 阅读
  4. Python语言-面向对象

    2024-03-28 05:28:10       91 阅读

热门阅读

  1. Android中的本地广播与全局广播

    2024-03-28 05:28:10       39 阅读
  2. 关于Docker守护程序未运行导致的错误

    2024-03-28 05:28:10       35 阅读
  3. 配置小程序的服务器域名

    2024-03-28 05:28:10       43 阅读
  4. MyBatis——实现级联表查询(一对一,一对多)

    2024-03-28 05:28:10       39 阅读