Go 奇淫技巧

  • 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())
}

发送邮件

  • 1 需要提前在邮箱设置好服务器
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)
  }
}

阿里发送短信

  • 1 需要准备阿里Key
  • 2 秘钥
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()
}
  • 3 更改后的代码: 200
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)
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容