- 1 map是无序的,不是线程安全, 可以利用切片来对map排序,使它成为有序的
- 2 利用切片保存map的值,sort包对切片进行排序.
func main(){
s:=map[string]int{
"wa":12,
"li":11,
"sa":18,
}
var name = make([]int, 0) // []string
for n := range s{
name = append(name,s[n])
}
fmt.Println(3333,name)
//利用切片对map的值排序,达到有序状态,根据值来进行排序,map键是唯一的,可以利用这个属性来去重!
sort.Ints(name) // sort.String()
for _,n:=range name{
for k,v:=range s{
if n==v{
fmt.Println(k,v)
}
}
}
}
2 获取本机电脑的IP地址
import "net"
func main() {
conn, _ := net.Dial("udp", "www.baidu.com:80")
defer conn.Close()
l := conn.LocalAddr().(*net.UDPAddr)
fmt.Println(l.IP.String())
}
发送邮件
type EmailInfo struct {
From string `json:"from"` //从哪里来
ToUser string `json:"to_user"` //到哪里去
Title string `json:"title"` //标题
Body string `json:"body"` //内容
Auth string `json:"auth"` //邮箱授权码
Port int `json:"port"` //邮箱端口
Server string `json:"server"` //邮箱服务器
}
func (e *EmailInfo)SendEmail()error{
if e.From == "" || e.ToUser == "" || e.Title == ""{
return errors.New("参数异常")
}
m := gomail.NewMessage()
m.SetHeader("From", e.From)
m.SetHeader("To", e.ToUser)
m.SetHeader("Subject", e.Title)
m.SetBody("text/html", e.Body)
d := gomail.NewDialer(e.Server, e.Port, e.From, e.Auth)
if err := d.DialAndSend(m); err != nil {
return err
}
return nil
}
func main(){
em := &EmailInfo{
From: "8726**@qq.com",
ToUser: "1234**@qq.com",
Title: "异常信息",
Body: "***具体内容",
Server: server,
Port: port,
Auth: auth,
}
if msg := em.SendEmail(); msg == nil {
panic(msg)
}
}
阿里发送短信
type ClientAliSms struct {
once sync.Once
client *sms.Client
}
func main() {
dat := `{"code":"1111"}`
res, err := NewClient().SendSimpleSms(&SimpleSendSmsRequest{
PhoneNumbers: "159****7989",
SignName: "**科技",
TemplateCode: "SMS_136871689",
TemplateParam: []byte(dat),
})
fmt.Println(res,err)
}
//使用AK&SK初始化账号Client
func NewClient() *ClientAliSms {
client := new(ClientAliSms)
client.once.Do(func() {
// 访问的域名
var err error
client.client, err = sms.NewClient(&openapi.Config{
AccessKeyId: tea.String(cfg.AliSmsAccessKeyId),
AccessKeySecret: tea.String(cfg.AliSmsAccessKeySecret),
Endpoint: tea.String(cfg.AliSmsEndpoint),
})
if err != nil {
vlog.ErrorPrintln("NewClient err", err)
}
})
return client
}
//发送短信消息!
func (s *ClientAliSms) SendSimpleSms(simple *SimpleSendSmsRequest) (*sms.SendSmsResponse, error) {
return s.client.SendSms(&sms.SendSmsRequest{
PhoneNumbers: tea.String(simple.PhoneNumbers),
SignName: tea.String(simple.SignName),
TemplateCode: tea.String(simple.TemplateCode),
TemplateParam: tea.String(string(simple.TemplateParam))})
}
正则匹配身份证的方法
import regexp
func f1(num string){
return len(regexp.MustCompile(`^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$`).FindAllStringSubmatch(num, -1)) > 0
}
gin框架分页返回数据到接口
- 1 根据数据的长度得出最大可以允许多少页,每页10条数据!
- 2 这种分页方式,适合放在Sql语句无法准确分页的情况下,比如Sql分页查询出的数据,每页有重复数据,或者每页不满10条数据,就可以使用以下方法!
func GetTaskCount(c *gin.Context) { //接口
size := apis.DefaultQuery(c, "limit", 10) //一页多少条
index := apis.DefaultQuery(c, "page", 1) //页
// 根据result的长度得出需要最大多少页返回数据给客户端!
maxPage := math.Ceil(float64(len(result)) / float64(size))
dat := make(map[string]interface{})
if index == 1 && len(result) < size {
dat["data"] = result[:]
}else if index == 1 && len(result) > size{
dat["data"] = result[:size*index]
}else if float64(index) == maxPage {
dat["data"] = result[size*(int(maxPage)-1):]
} else if float64(index) < maxPage {
dat["data"] = result[size*(index-1):size*index]
} else {
dat["data"] = []int
}
c.JSON(http.StatusOK, dat)
}
计算闰年
year := 2020
//闰年的计算方法
if year%4==0 && year % 100 != 0 || year % 400==0{
fmt.Println("是闰年",year)
}else{
fmt.Println("不是闰年",year)
}
GO没有像Python in 的包含操作,可以通过一是遍历,二是 sort 的二分查找,三是 map 的 key 索引 实现包含
1 遍历
func InSlice(data []int, s int)bool{
for _,v:=range data{
if s == v{
return true
}
return false
}
}
2 二分法查找,数据量太大,时间复杂度变成log2(n) ,前提是该序列得是有序的
func InSlice(){
b := []int{3,2,1,55,33}
sort.Ints(b) // 没有返回值的函数,提前排好序才行
a := sort.SearchInts(b, len(b)) // 返回值的下标,通过下标就能判断是不是包含该值
// a < len(b) && b[a] == len(b) 越界的情况需要注意!
fmt.Println(a)
}
3 map[key] 来判断是否包含! 在数据量大的时候这种是性能最快的。
func main() {
a := []string{"aa","bb","dd"}
b := "bb"
m := make(map[string]string, len(a))
for _,v := range a{
m[v] = "123"
}
if v,ok := m[b];ok{
fmt.Println("有值:",v)
}else{
fmt.Println("无值...")
}
}
sync.Mutex 互斥锁的位置会影响并发后的数据
- 1 如果是并发读取而不写入数据,可以用RWMutex
- 2 互斥锁的位置会影响结构,下面代码输出的数值按理是200,可是它是变化的,有时199不一定的
func main(){
wg := sync.WaitGroup{}
var a int
for i:=0;i<200;i++{
wg.Add(1)
go f2(&a,&wg)
}
wg.Wait()
fmt.Println("总数值为:", a)
}
func f2(a *int, wg *sync.WaitGroup){
var mutex sync.Mutex
mutex.Lock()
*a++
mutex.Unlock()
wg.Done()
}
func main(){
var mutex sync.Mutex
wg := sync.WaitGroup{}
var a int
for i:=0;i<200;i++{
wg.Add(1)
go f2(&a,&mutex,&wg)
}
wg.Wait()
fmt.Println("总数值为:", a) // 保持了数据同步: 200
}
func f2(a *int,mutex *sync.Mutex, wg *sync.WaitGroup){
mutex.Lock()
*a++
mutex.Unlock()
wg.Done()
}
浮点数转换成字符串,又保留有效位数,去掉无效的 0
func main() {
a := 12097840.76346754000000000000
d := math.Pow10(5) // 保留小数点后5位 12097840.76346
v := strconv.FormatFloat(math.Trunc(a*d)/d, 'f', -1, 64)
fmt.Println(v,d)
}