那些奇怪的用法
代码中的指令
//go:build
//go:cgo_dynamic_linker
//go:cgo_export_dynamic
//go:cgo_export_static
//go:cgo_import_dynamic
//go:cgo_import_static
//go:cgo_ldflag
//go:cgo_unsafe_args
//go:embed
//go:generate
//go:linkname
//go:name
//go:noescape
//go:noinline
//go:nosplit
//go:registerparams
//go:systemstack
//go:uintptrescapes
//go:xxx
//go:yeswritebarrierrec
2006-01-02T15:04:05 有什么用?
fstest 中的 var _ fs.FS = MapFS(nil) 有什么用?
fstest 中的 var _ fs.File = (*openMapFile)(nil) 有什么用?
n := 2; fmt.Println(string(n)) 输出却是空的!或者不能编译通过!为什么?
 因为:string()转化:conversion from int to string yields a string of one rune, not a string of digits (将 int类型的值通过string()进行转化,会产生某一个rune字符对应的字符串,而不是产生对应数值的字符串),而这里的 n 是 int 类型!
1
2
3
4
5
6
7
8
  | package main
func main() {
    n := 2
    str := string(n)
    fmt.Println(str)
    //fmt.Printf("str=%q,len=%d\n",str,len(str))  // str="\x02",len=1
}
  | 
 又因\x02 ,十进制编码值为 2,对应ASCII 码中的 “Start of Text” 控制字符,显示为 ^B
 \x02在不同的环境下显示效果可能不同:
- 在终端中,它通常不显示任何可见字符
 - 在文本编辑器中,可能显示为 
^B - 在浏览器中,可能显示为一个小方块 
□ 
func New() gdb.Driver { return &Driver{} } 为什么需要使用 &?
1
2
3
  | func New() gdb.Driver {
    return &Driver{}
}
  | 
gdb.Driver的定义
1
2
3
4
  | type Driver interface {
	// New creates and returns a database object for specified database server.
	New(core *Core, node *ConfigNode) (DB, error)
}
  | 
Driver的定义
1
2
3
  | type Driver struct {
	*gdb.Core
}
  | 
gdb.Core的定义
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
  | type Core struct {
	db            DB              // DB interface object.
	ctx           context.Context // Context for chaining operation only. Do not set a default value in Core initialization.
	group         string          // Configuration group name.
	schema        string          // Custom schema for this object.
	debug         *gtype.Bool     // Enable debug mode for the database, which can be changed in runtime.
	cache         *gcache.Cache   // Cache manager, SQL result cache only.
	links         *gmap.StrAnyMap // links caches all created links by node.
	logger        glog.ILogger    // Logger for logging functionality.
	config        *ConfigNode     // Current config node.
	dynamicConfig dynamicConfig   // Dynamic configurations, which can be changed in runtime.
}
  | 
 我们先将以上相关代码做下简化:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  | package main
import "fmt"
// gdb.Driver -> A
type A interface {
	F()
}
// Driver -> a
type a struct {
	b
}
func (ar a) F() {}
// gdb.Core -> b
type b struct {
	V string
}
func New1() A {
	return &a{}
}
func New2() A {
	return a{}
}
func main() {
	v1 := New1()
	v2 := New2()
	fmt.Printf("%T, %#v\n", v1, v1)
	fmt.Printf("%T, %#v\n", v2, v2)
}
*main.a, &main.a{b:main.b{V:""}}
main.a, main.a{b:main.b{V:""}}
  | 
 我们发现实际上无论是否使用&这个符号,返回的值都是满足 A这个接口的。使用&只是减少数据的拷贝, 如果 a 是一个很大的结构体(包含很多字段或嵌入字段),不使用&,势必会发生拷贝时间长等问题。