nil 是 interface、function、pointer、map、slice 和 channel 类型变量的默认初始值
不可以用"=="比较类型: slice(切片)、map(key-value集合)、func(函数)
Go 语言采用的是哈希查找表,并且使用链表解决哈希冲突。go1.9以后(含)。源码src/runtime/map.go
map的比较可以使用reflect.DeepEqual()
m1 := map[string]string{"one": "a", "two": "b"}
m2 := map[string]string{"two": "b", "one": "a"}
// 1.map类型的值的比较,常规的思路:1). 比较长度是否相等. 2). 比较key是不是相等 3). 比较相同key的value是不是相等
if len(m1)!=len(m2){
fmt.Println("!=")
return
}
for k, v := range m1 {
if _,ok:=m2[k];!ok{
fmt.Println("!=",i)
return
}
if m2[k]!=v{
fmt.Println("!=")
return
}
}
for k, v := range m2 {
if _,ok:=m1[k];!ok{
fmt.Println("!=")
return
}
if m1[k]!=v{
fmt.Println("!=")
return
}
}
fmt.Println("==")
// 2. equal := reflect.DeepEqual(m1, m2) //性能有时稍差
fmt.Println("v1 == v2: ",equal )
如果要大小写不敏感来比较 byte 或 string 中的英文文本,可以使用 “bytes” 或 “strings” 包的 ToUpper() 和 ToLower() 函数。比较其他语言的 byte 或 string,应使用 bytes.EqualFold() 和 strings.EqualFold()
如果 byte slice 中含有验证用户身份的数据(密文哈希、token 等),不应再使用 reflect.DeepEqual()、bytes.Equal()、 bytes.Compare()。这三个函数容易对程序造成 timing attacks,此时应使用 “crypto/subtle” 包中的 subtle.ConstantTimeCompare() 等函数
reflect.DeepEqual() 认为空 slice 与 nil slice 并不相等,但注意 byte.Equal() 会认为二者相等:
var b1 []byte = nil
b2 := []byte{}
fmt.Println(reflect.DeepEqual(b1,b2),bytes.Equal(b1,b2)) //false true
string的len是字节长度,英文1个字节,中文3个字节
字符长度
str:="zh里"
runes := []rune(str)
fmt.Println(len(runes))
截取的值为ASCII码.
如果要得到字符串的字符数,可使用 “unicode/utf8” 包中的 RuneCountInString(str string) (n int)
str2 := "A♥C中"
fmt.Println(utf8.RuneCountInString(str2),len(str2)) // 4,8
char := "é" //法语
fmt.Println(len(char)) // 2
fmt.Println(utf8.RuneCountInString(char)) // 1
fmt.Println("cafe\u0301") 法语café
## string 到float
strconv.FormatFloat(input_num,'f',6,64) //6为小数位数,-1全部精度
#string到int
int,err:=strconv.Atoi(string)
#string到int64
int64, err := strconv.ParseInt(string, 10, 64)
#int到string
string:=strconv.Itoa(int)
#int64到string
string:=strconv.FormatInt(int64,10)
golang获取当前时间、时间戳和时间字符串及它们之间的相互转换
1、获取当前时间
(1) currentTime:=time.Now() //获取当前时间,类型是Go的时间类型Time
(2)
t1:=time.Now().Year() //年
t2:=time.Now().Month() //月
t3:=time.Now().Day() //日
t4:=time.Now().Hour() //小时
t5:=time.Now().Minute() //分钟
t6:=time.Now().Second() //秒
t7:=time.Now().Nanosecond() //纳秒
currentTimeData:=time.Date(t1,t2,t3,t4,t5,t6,t7,time.Local) //获取当前时间,返回当前时间Time
fmt.Println(currentTime) //打印结果:2017-04-11 12:52:52.794351777 +0800 CST
fmt.Println(t1,t2,t3,t4,t5,t6) //打印结果:2017 April 11 12 52 52
fmt.Println(currentTimeData) //打印结果:2017-04-11 12:52:52.794411287 +0800 CST
说明:从打印结果可以看出,time.Now()和Date()方法都可以获取当前时间,time.Now()用起来比较简单,但是Date()可以获取不同的精确值,如time.Date(t1,t2,t3,t4,t5,t6,0,time.Local)将毫秒省略,精确到秒,结果为:2017-04-11 12:52:52 +0800 CST
2、获取当前时间戳
timeUnix:=time.Now().Unix() //单位s,打印结果:1491888244
timeUnixNano:=time.Now().UnixNano() //单位纳秒,打印结果:1491888244752784461
3、获取当前时间的字符串格式
timeStr:=time.Now().Format("2006-01-02 15:04:05") //当前时间的字符串,2006-01-02 15:04:05据说是golang的诞生时间,固定写法
fmt.Println(timeStr) //打印结果:2017-04-11 13:24:04
4、它们之间的相互转化
1) 时间戳转时间字符串 (int64,time.Time —> string)
unix := time.Unix(timeUnix, 0) //类型为time.Time
timeUnix:=time.Now().Unix() //已知的时间戳
formatTimeStr:=time.Unix(timeUnix,0).Format("2006-01-02 15:04:05")
fmt.Println(formatTimeStr) //打印结果:2017-04-11 13:30:39
或 parse1:= time.Now().Format("2006-01-02 15:04:05") //2020-07-29 10:12:12
2) 时间字符串转时间(string —> time.Time)
datetime := "2019-07-29 22:32:49"
parse, _ := time.Parse("2006-01-02 15:04:05", datetime)
fmt.Println(parse) //2019-07-29 22:32:49 +0000 UTC
或
tmp, _ := time.ParseInLocation("2006-01-02 15:04:05", datetime, time.Local) //2019-07-29 22:32:49 +0800 CST
3) 时间字符串转时间戳 (string —> int64)
比上面多一步,parse.Unix()即可
4). yyyy-mm-dd string to yyyymmdd string
strings.Replace(input, "-", "", -1)
:
package main
func main(){
b:=20
println(b)
}
a,b,c,d:=1,2,2,4
fmt.Println(a,b,c,d)
var a,b int8 //(这里int8改为uint8,byte都可以输出a,s对应的ascII码值)
a='a'
b='s'
b=a
//a=b //这边打开也不会输出
fmt.Println(a,b) //97,97
var a uint8 = 8
var b byte = 'a'
b=a
//a=b //这边打开也不会输出
fmt.Println(a,b) //8,8
//var a,b,s=20,30,"haha"
a,b,s:=15,20,"aa"
fmt.Println(a,b,s)
上面两种赋值方式结果相同
变量再次赋值时,不能加var
5. 数据类型
var num1 int = 99
var num2 float64 = 3.123
var b bool = true
var myChar byte = 'h'
var str string
str=fmt.Sprintf("%d",num1)
fmt.Printf("str type:%T str=%q\n",str,str)
str=fmt.Sprintf("%f",num2)
fmt.Printf("str type:%T str=%q\n",str,str)
str=fmt.Sprintf("%t",b)
fmt.Printf("str type:%T str=%q\n",str,str)
str=fmt.Sprintf("%c",myChar)
fmt.Printf("str type:%T str=%q\n",str,str)
结果
str type:string str=“99”
str type:string str=“3.123000”
str type:string str=“true”
str type:string str=“h”
10. 输入
fmt.scanf("%d,&a)或 fmt.scan(&a)
11. 运算符
<< ,相当于乘以2的n次方
>>
,正数右移最小为0,负数最小为-1
负数移位按原码
按位运算按补码
类型转换使用math/big
Go 语言 big.Int
NewInt() 函数只对 int64 有效,其他类型必须先转成 int64 才行。转换使用set方法
func main() {
big1 := new(big.Int).SetUint64(uint64(1000))
fmt.Println("big1 is: ", big1)
big2 := big1.Uint64()
fmt.Println("big2 is: ", big2)
}
big 库还提供了一个 SetString() 函数,可以指定进制数,比如二进制、十进制或者十六进制等!
func main() {
big1 := new(big.Int).SetString("1000", 10)
fmt.Println("big1 is: ", big1)
big2 := big1.Uint64()
fmt.Println("big2 is: ", big2)
}
uint64, int64 等普通类型与 big.Int 类型的转换:
直接调用 big 库提供的 Int64(), Uint64() 等函数就可以进行转换。
转换为string
bigint:= big.NewInt(123)//新建
bigstr:= bigint.String()
2.转换为int64, bigint.Int64()
3. big.Int 类型比较
enough := bigWeiBalance.Cmp(bigWeiValue)
使用cmp方法
返回 1:前面的big.Int 实例(bigWeiBalance)大于cmp方法big.Int 参数(bigWeiValue)
返回 0:前面的big.Int 实例等于cmp方法big.Int 参数
返回-1:前面的big.Int 实例小于cmp方法big.Int 参数
分支语句时,注意后面的分支不要再使用:推导
不使用科学计数法输出,
sprintf := fmt.Sprintf("%.18f", float)
f前面的数字为你决定要保留多少位小数.