1.math
math.Sqrt(x float64) float64
math.Min(x float64,y float64) float64
b := 1 //int
a := math.Sqrt(float64(b)) //只接收float64类型,故需进行类型转换
if a > b //wrong,比较时类型必须一致
if int(a) > b //right
常量:leetcode73
const x = math.MaxInt32
1.常量编译时就确定值,之后不可重新赋值
2.函数调用发生在运行时,所以不能将函数的返回值赋值给常量
func main() {
fmt.Println("Hello, playground")
var a = math.Sqrt(4) // 允许
const b = math.Sqrt(4) // 不允许
}
math.Abs(float64)
leetcode29
32位有符号整数,其数值范围是 [−2^31, 2^31 − 1]。
一位符号位,剩余31位,[-2^31, +2^31],但是这样0多算了一次,故减一。
math/rand
rand.Intn () 函数是个伪随机函数,不管运行多少次都只会返回同样的随机数,因为它默认的资源就是单一值。
故调用 rand.Seed (), 并且传入一个变化的值作为参数,如 time.Now().UnixNano() , 就是可以生成时刻变化的值
func main() {
rand.Seed(time.Now().UnixNano())
for i := 0; i < 10; i++ {
x := rand.Intn(100) // 0 <= x < 100
fmt.Println(x)
}
}
2.container/list 实现双向链表 leetcode341
container包:https://ijayer.github.io/post/tech/code/golang/tutorial-go36-03/
// 节点结构体
type Element struct {
// 前后节点指针
next, prev *Element
// 链表指针,用于标识该节点属于哪一个链表,链表插入和删除时会根据此字段进行判断
list *List
// 节点的值
Value interface{}
}
// 链表结构体
type List struct {
// 相当于头节点,go 中使用 root 属性将整个链表首尾连接起来,使其可以快速向链表首尾进行操作,可参考向首尾插入方法
root Element
// 链表长度
len int
}
Q:remove和Remove区别
Q:remove函数移除节点e,为什么要将e.next置为nil?
func (l *List) remove(e *Element) *Element
避免内存泄露啥意思?
Q:Element.list:指向当前这个节点所属的链表的指针
3.unsafe.Pointer
go不允许指针之间进行类型转换,eg.*int to float64
unsafe.Pointer类似void,万能指针,作为中间过渡,实现类型转换
a := 10
a1 := &a
b := *float64(a1) //wrong
b := *float64(unsafe.Pointer(a1)) //right
https://www.flysnow.org/2017/07/06/go-in-action-unsafe-pointer.html
4.sync.Mutex/sync.RWMutex
https://www.jianshu.com/p/679041bdaa39