syntax update 1.20

main
han-joker 2 years ago
commit 71309058cd

42
.gitignore vendored

@ -0,0 +1,42 @@
# Reference https://github.com/github/gitignore/blob/master/Go.gitignore
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
vendor/
# Go workspace file
go.work
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# OS General
Thumbs.db
.DS_Store
# project
*.cert
*.key
*.log
bin/
# Develop tools
.vscode/
.idea/
*.swp
# volumes
data/

@ -0,0 +1 @@
# Go核心语法

@ -0,0 +1,72 @@
package goSyntax
import (
"embed"
"fmt"
"io/fs"
"log"
"net/http"
"os"
)
// 嵌入单文件
// 文本文件
//
//go:embed files/robots.txt
var robots string
// 二进制文件
//
//go:embed files/logo.png
var logo []byte
func EmbedFile() {
fmt.Println(robots)
fmt.Println(logo)
}
// 嵌入目录
//
//go:embed files
var files embed.FS
func EmbedDir() {
// 获取目录下的全部文件
entries, err := files.ReadDir("files")
if err != nil {
log.Fatal(err)
}
// 以此输出每个文件的信息
for _, entry := range entries {
info, _ := entry.Info()
fmt.Println(entry.Name(), entry.IsDir(), info.Size())
}
// 读取文件内容
content, _ := files.ReadFile("files/robots.txt")
fmt.Println(string(content))
}
// 基于embed的http服务器
// 嵌入静态目录
//
//go:embed static
var static embed.FS
// 启动服务器
func StaticEmbedServer() {
// 获取嵌入的static子目录作为文件系统
staticFS, _ := fs.Sub(static, "static")
// 基于static的FS创建 http.FS
// 基于http.FS创建 http.FileServer
// 启动监听 :8080
http.ListenAndServe(":8080", http.FileServer(http.FS(staticFS)))
}
// 非嵌入,运行时读取静态文件的服务器
func StaticRuntimeServer() {
// os.DirFS 基于操作系统的目录文件系统
staticFS := os.DirFS("static")
http.ListenAndServe(":8081", http.FileServer(http.FS(staticFS)))
}

@ -0,0 +1,19 @@
package goSyntax
import "testing"
func TestEmbedFile(t *testing.T) {
EmbedFile()
}
func TestEmbedDir(t *testing.T) {
EmbedDir()
}
func TestStaticEmbedServer(t *testing.T) {
StaticEmbedServer()
}
func TestStaticRuntimeServer(t *testing.T) {
StaticRuntimeServer()
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

@ -0,0 +1,4 @@
User-agent: Baiduspider
Disallow:
User-agent: *
Disallow: /

Binary file not shown.

Binary file not shown.

@ -0,0 +1,5 @@
package goSyntax
func Add(a, b uint8) uint8 {
return a + b
}

@ -0,0 +1,65 @@
package goSyntax
import (
"fmt"
"os"
"testing"
)
// Add的单元测试
func TestAdd(t *testing.T) {
// 定义测试用例
type item struct {
a, b, s uint8
}
items := []item{
{1, 1, 2},
{10, 56, 66},
{100, 101, 201},
{123, 1, 124},
}
// 执行测试(若有错误,报告)
for _, v := range items {
s := Add(v.a, v.b)
if s != v.s {
t.Errorf("a: %d, b: %d, s: %d", v.a, v.b, s)
}
}
}
// Add 的模糊测试
func FuzzAdd(f *testing.F) {
// 一,添加测试用例种子(到语料库中)
// 要与测试函数Add保持一致值随意
f.Add(uint8(2), uint8(3))
// 额外:将生成的模糊测试用例,写入到文件中
file, _ := os.OpenFile("./fuzz_input.txt", os.O_CREATE|os.O_TRUNC, 0644)
defer file.Close()
// 二,执行测试,基于模糊数据完成测试
f.Fuzz(func(t *testing.T, a, b uint8) {
// 额外记录下ab的值
// 实现测试
s := Add(a, b)
fmt.Fprintf(file, "a:%d, b:%d, s:%d\n", a, b, s)
// 模糊测试,由于数据随机生成,因此结果也是随机的
// 必须要找到可以判定是否结果正确的方法。
if s-a != b {
// 模拟可能错误的检测逻辑
//if int(s)-int(a) != int(b) {
t.Errorf("a: %d, b: %d, s: %d", a, b, s)
}
})
}
func FuzzSeed(f *testing.F) {
// 添加string类型的种子
f.Add("mashibing")
file, _ := os.OpenFile("./fuzz_input.txt", os.O_CREATE|os.O_TRUNC, 0666)
defer file.Close()
f.Fuzz(func(t *testing.T, s string) {
fmt.Fprintf(file, "%s\n", s)
})
}

@ -0,0 +1,272 @@
package goSyntax
import (
"fmt"
"sync"
)
func GenericDef() {
// 一:泛型类型的定义
// 使用类型参数来定义类型
type mySlice[P int | string] []P
// 泛型类型 mySlice[P]
type myMap[K int | string, V float64 | float32] map[K]V
type myList[T int | float64] struct {
data []T
l int
max, min, avg T
}
// 二:声明泛型类型的变量
// 泛型类型的的实例化,得到了具体的 []int, []string
_ = mySlice[int]{1, 2, 3, 4}
_ = mySlice[string]{"one", "two", "three", "four"}
// 注意:泛型不是那种类型都可以的意思,不是弱类型的概念
//_ = mySlice[int|string]{1, 2, "three", "four"}
_ = myMap[string, float32]{ // map[string]float32
"go": 99.5,
}
_ = myList[int]{
data: []int{1, 2, 3},
max: 3,
}
// 三,测试数据的类型
fmt.Printf("%T\n", mySlice[int]{1, 2, 3, 4})
fmt.Printf("%T\n", mySlice[string]{"one", "two", "three", "four"})
fmt.Printf("%T\n", myMap[string, float32]{ // map[string]float32
"go": 99.5,
})
fmt.Printf("%T\n", myList[int]{
data: []int{1, 2, 3},
max: 3,
})
}
func GenericExt() {
// 一:类型约束为基础类型
// ~
type intSlice[P ~int] []P
_ = intSlice[int]{}
// 以int为基础类型的自定义类型
type myInt int
type yourInt myInt
_ = intSlice[myInt]{}
_ = intSlice[yourInt]{}
// Cannot use int32 as the type interface{ ~int }
//_ = intSlice[int32]{}
// 二,基于泛型类型,继续定义泛型类型
type mySlice[T int | string | float32 | float64] []T
// mySlice[T]
type floatSlice[T float32 | float64] mySlice[T]
//
type myStruct[T float32 | float64] struct {
FieldA mySlice[T]
}
// 三:错误语法注意
// 类型即可是int也可是string
//type myT[T int | string] T
//type myT interface{ int | string }
type T1[P *int,] []P
type T2[P interface{ *int }] []P
}
// 一:定义泛型类型
type myList[T int | float64 | int32 | float32] struct {
data []T
max, min T
m sync.Mutex
}
// 二:定义泛型类型的方法集
// 1, 添加元素,更新最大值最小值
// 泛型接收器, 泛型类型参数类型
func (l *myList[T]) Add(ele T) *myList[T] {
// 加锁并发安全考虑
l.m.Lock()
defer l.m.Unlock()
// 更新 data
l.data = append(l.data, ele)
// 统计 min max
if len(l.data) == 1 {
l.max = ele
l.min = ele
}
if ele > l.max {
l.max = ele
}
if ele < l.min {
l.min = ele
}
return l
}
// 2, 获取元素
func (l myList[T]) All() []T {
return l.data
}
func (l myList[T]) Max() T {
return l.max
}
func (l myList[T]) Min() T {
return l.min
}
func GenericReceiver() {
//l := myList[int]{}
l := myList[float64]{}
// 添加
l.Add(1.1).Add(3.3).Add(10.01)
// 获取元素
fmt.Println(l.All())
fmt.Println(l.Max(), l.Min())
}
type Queue[T int | string] struct {
data []T
}
func (q *Queue[T]) Put(v ...T) *Queue[T] {
q.data = append(q.data, v...)
return q
}
func (q *Queue[T]) Pop() (T, bool) {
var v T
if len(q.data) == 0 {
return v, true
}
v = q.data[0]
q.data = q.data[1:]
return v, len(q.data) == 0
}
func (q Queue[T]) Size() int {
return len(q.data)
}
// 泛型函数求和
func Sum[T int | string](ele ...T) T {
var s T
for _, v := range ele {
s += v
}
func(n T) {
}(s)
return s
}
func GenericFunc() {
// 显式指定类型,调用函数
fmt.Println(Sum[int](1, 2, 3))
fmt.Println(Sum[string]("ma", "shi", "bing"))
}
func GenericInference() {
// 显式指定类型,调用函数
fmt.Println(Sum(1, 2, 3))
fmt.Println(Sum("ma", "shi", "bing"))
}
func GuessType[T int | string](ele ...T) T {
var s T
for _, v := range ele {
s += v
}
func(n T) {
}(s)
return s
}
func TypeInference() {
//
fmt.Println(GuessType[int](1, 2, 3))
fmt.Println(GuessType[string]("Ma", "Shi", "Bing"))
// 类型推断
fmt.Println(GuessType(1, 2, 3))
fmt.Println(GuessType("Ma", "Shi", "Bing"))
// 全部指定
GuessType2[int, string](42, "Ma")
// 指定前面部分
GuessType2[int](42, "Ma")
// 指定后边部分
GuessType2(42, "Ma")
// 合理
GuessType3(42, []int{})
// 不合理
//GuessType3(42, []string{})
}
func GuessType2[K int | string, V float64 | string](p1 K, p2 V) {
}
func GuessType3[K int | string, V []K](p1 K, p2 V) {
}
// 泛型接口 generate interface
type Data[T int | string] interface {
Process(T) (T, error)
Save() error
}
func GenerateInterface() {
// JsonData 实现了 Data[string]
DataOperate(JsonData{})
// NumberData 没有实现 Data[string]
//DataOperate(NumberData{})
DataOperateInt(NumberData{})
}
func DataOperate(p Data[string]) {
}
func DataOperateInt(p Data[int]) {
}
// Data[string] 相当于
//type Data interface {
// Process(string) (string, error)
// Save() error
//}
// 实现接口的类型
type JsonData struct{}
func (JsonData) Process(string) (string, error) {
return "", nil
}
func (JsonData) Save() error {
return nil
}
type NumberData struct{}
func (NumberData) Process(int) (int, error) {
return 0, nil
}
func (NumberData) Save() error {
return nil
}

@ -0,0 +1,27 @@
package goSyntax
import "testing"
func TestGenericDef(t *testing.T) {
GenericDef()
}
func TestGenericExt(t *testing.T) {
GenericExt()
}
func TestGenericReceiver(t *testing.T) {
GenericReceiver()
}
func TestTT(t *testing.T) {
GenericInference()
}
func TestGenericFunc(t *testing.T) {
GenericFunc()
}
func TestTypeInference(t *testing.T) {
TypeInference()
}

@ -0,0 +1,8 @@
module goSyntax
go 1.19
require (
github.com/tobert/pcstat v0.0.1 // indirect
golang.org/x/sys v0.6.0 // indirect
)

@ -0,0 +1,5 @@
github.com/tobert/pcstat v0.0.1 h1:NxXAb8Jxb98oagaTvdvnB0t4dsThQmGxMRZ+OJf2WTY=
github.com/tobert/pcstat v0.0.1/go.mod h1:VKepz+gb+o6C1PlINP9Qoz5PDEPM2VLRJsilEHwfD+4=
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

@ -0,0 +1,74 @@
package goSyntax
// 基本接口,方法集
type ReadWriter interface {
Read(p []byte) (int, error)
Write(p []byte) (int, error)
}
// 一般接口,仅包含类型集(类型约束)
type Float interface {
~float32 | ~float64
}
// 一般接口,同时包含方法集合类型集的接口
type FloatReadWriter interface {
~float32 | ~float64
Read(p []byte) (int, error)
Write(p []byte) (int, error)
}
// 实现接口
// 基本接口,方法集
type rw struct{}
func (rw) Read(p []byte) (int, error) { return 0, nil }
func (rw) Write(p []byte) (int, error) { return 0, nil }
// 实现接口
// 一般接口,类型集
type myFloat float32
func (myFloat) Read(p []byte) (int, error) { return 0, nil }
func (myFloat) Write(p []byte) (int, error) { return 0, nil }
type yourFloat float64
// 调用测试
func funcMS(p ReadWriter) {
}
// interface includes constraint elements '~float32', '~float64', can only be used in type parameters
// func funcGI(p Float) {}
func funcGI[T Float]() {}
func funcGI2[T FloatReadWriter]() {}
// 测试函数
func TypeSet() {
// 传统的接口(基础接口)
funcMS(rw{})
// myFloat, yourFloat, float32, float644中类型的基础类型满足Float接口
funcGI[myFloat]()
funcGI[yourFloat]()
funcGI[float32]()
funcGI[float64]()
// myFloat 满足以float32为基础类型同时实现了Read和Write
funcGI2[myFloat]()
// 而 yourFloat, float32, float64没有实现Read和Write
//funcGI2[yourFloat]()
//funcGI2[float32]()
//funcGI2[float64]()
}
type Empty interface {
int
string
}
type myMap[K comparable, V any] map[K]V
//type yourMap[K any, V any] map[K]V

@ -0,0 +1,4 @@
User-agent: Baiduspider
Disallow:
User-agent: *
Disallow: /

@ -0,0 +1,22 @@
package main
import (
_ "embed"
"fmt"
)
// 嵌入单文件
// 文本文件
//
//go:embed files/robots.txt
var robots string
// 二进制文件
//
//go:embed files/logo.png
var logo []byte
func main() {
fmt.Println(robots)
fmt.Println(logo)
}

@ -0,0 +1,8 @@
.main-container {
width: 300px;
height: 500px;
background-color: red;
}
.main-logo {
width: 120px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

@ -0,0 +1,17 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="css/style.css">
<title>马士兵教育</title>
</head>
<body>
<h1>Go语言语法更新</h1>
<img src="img/logo.png" alt="" class="main-logo">
<div class="main-container"></div>
<script src="js/script.js"></script>
</body>
</html>

@ -0,0 +1 @@
console.log("JS run")
Loading…
Cancel
Save