包含标签 golang 的文章

Golang 的 reflect 包和 unsafe 包

一、reflect 包 基于反射的代码是比较脆弱的 反射的操作不能做静态类型检查,而且大量反射的代码通常难以理解 基于反射的代码通常比正常的代码运行速度慢一到两个数量级 二、unsafe 包 unsafe 包用于实现比较低层级的包,如 runtime、syscall 三、cgo 编程 在没有 golang 实现的可用工程包时,不得以而使用 c/c++ 实现的库时,使用 cgo 来调用 package main /* #include <stdint.h> static int32_t max(int32_t x, int32_t y) { return (x > y) ? x : y; } */ import "C" import "fmt" func main() { var x, y int32 = 2, 6 var z int32 = int32(C.max(C.int32_t(x), C.int32_t(y))) fmt.Println(z) // 6 } // 注意*: import "C" 要紧跟 c/c++ 代码 ……

阅读全文

Golang 测试

一、 go test go test命令会遍历所有的*_test.go文件中符合上述命名规则的函数,然后生成一个临时的main包用于调用相应的测试函数,然后构建并运行、报告测试结果,最后清理测试中生成的临时文件。 二、 测试函数 函数原型 func TestName(t *testing.T) { // ... } // 1> 测试函数的名字必须以Test开头,可选的后缀名必须以大写字母开头 每个测试函数必须导入 testing 包 package word import "testing" func TestPalindrome(t *testing.T) { if !IsPalindrome("detartrated") { t.Error(`IsPalindrome("detartrated") = false`) } if !IsPalindrome("kayak") { t.Error(`IsPalindrome("kayak") = false`) } } func TestNonPalindrome(t *testing.T) { if IsPalindrome("palindrome") { t.Error(`IsPalindrome("palindrome") = true`) } } 测试命令 go test 用来执行测试用例 go test -v 显示每个函数的执行时间 go test -v -run=“函数1|函数2” , -run 对应一个正则表达式,只有测试函数名被它正确匹配的测试函数才会被 go test 测 试命令运行……

阅读全文

Golang方法

Go语言借助方法来实现OOP Go语言OOP的两个关键是封装和组合 一、方法 方法是属于某种类型的,方法可以被声明到任意类型,只要不是一个指针或者一个interface。 值类型和引用类型: (1)值类型包括:基本数据类型int系列、float系列、bool、string、数组和结构体; (2)引用类型:指针、slice切片、map、管道channel、interface等; 值类型和引用类型的区别: (1)值类型,变量直接存储,内存通常在栈中分配; (2)引用类型:变量存储的是一个地址,这个地址对应的空间才是真正存储的数据值,内存通常在堆上分配,当没有任何变量引用这个地址时,此地址对应的数据空间就是一个垃圾,由GC来回收; type Point struct { x, y float64 } //function func Distance(p, q Point) float64 { return math.Hypot(q.x-p.x, q.x-p.x) } //method //p为方法的接收器(receiver),接收器的名字建议用类型的第一个字母或第2个word的第一个字母 func (p Point) Distance(q Point) float64 { return math.Hypot(q.x-p.x, q.y-p.y) } p := Point{1, 2} q := Point{4, 6} fmt.Println(Distance(p, q)) // "5", function call fmt.Println(p.Distance(q)) // "5", method call //p.Distance被称为选择器 //计算线段的长度 // A Path is a journey connecting the points with straight lines.……

阅读全文

Golang函数

一、函数定义 函数声明包括函数名、形式参数列表、返回值列表(可省略)以及函数体。 func name(parameter-list) (result-list) { body } func add(x int, y int) int {return x + y} func sub(x, y int) (z int) { z = x - y; return} func first(x int, _ int) int { return x } func zero(int, int) int { return 0 } fmt.Printf("%T\n", add) // "func(int, int) int" fmt.Printf("%T\n", sub) // "func(int, int) int" fmt.Printf("%T\n", first) // "func(int, int) int" fmt.Printf("%T\n", zero) // "func(int, int) int" 二、递归 函数可以调用函数自身。 func f(n int) int { if n == 1 || n == 2 { return 1 } return f(n-1) + f(n-2) } 三、多返回值函数 Go可以返回多个值给调用者……

阅读全文

Golang 包和工具

一、 Go 编译快 依赖关系判断 第一点,所有导入的包必须在每个文件的开头显式声明,这样的话编译器就没有必要读取和分析整个源文件来判断包的依赖关系。 禁止环状依赖 第二点,禁止包的环状依赖,因为没有循环依赖,包的依赖关系形成一个有向无环图,每个包可以被独立编译,而且很可能是被并发编译。 记录依赖关系 第三点,编译后包的目标文件不仅仅记录包本身的导出信息,目标文件同时还记录了包的依赖关系。 二、 导入路径 import 语句是导入的包路径,不是包名。 三、 包声明 每个 Go 语言源文件的开头都必须有包声明语句(即指明包名) 通常情况下,默认的包名就是包导入路径名的最后一段。 例外情况: main包的路径无关紧要 以 _test 结束的包名,即测试包,可与其它包在同一路径下共存 包含版本号的导入路径, 如 “gopkg.in/yaml.v2”。这种情况下包的名字并不包含版本号后缀,而是yaml。 四、 导入声明 有两种形式 // 形式一 import "fmt" import "os" //形式二 import ( "fmt" "os" ) 通常将来自不同组织的包用空行分组 import ( "fmt" "html/template" "os" "golang.org/x/net/html" "golang.org/x/net/ipv4" ) 导入包重命名 import ( "crypto/rand" mrand "math/rand" // alternative name mrand avoids conflict ) 五、 包的匿名导入 导入包不使用包,会导致编译错误……

阅读全文