创建一个错误

package main

import (
    "errors"
    "fmt"
)

func main() {
    err := fmt.Errorf("123123")
    fmt.Println("err1:", err)  //err1: 123123

    err = errors.New("math: square root of negative number")
    fmt.Println("err:2", err) //err:2 math: square root of negative number

    name := getError("name no is empty.")
    fmt.Println(name) //I am err massage.name no is empty.
}

func getError(str string) error{
 return errors.New("I am err massage."+str)
}

数组分批处理

func GKDataImport() {
    //t := `2021-09-27 22:18:32`
    //t = strings.Replace(t, " ", "_", -1)
    //fmt.Println(t)
    //return
    var filePath string
    //filePath = "log/jsonTagData/company.json"
    filePath = config.CONFIG.EsClient.SourceFilePath
    list := make([]saveGongKongData, 0, 1000)
    file, err := os.Open(filePath)
    if err != nil {
        fmt.Println("GKDataImport os.Open(filePath) err:", err)
        return
    }
    defer file.Close()

    scanner := bufio.NewReader(file)
    var errDataIds []string
    // total 总共读取的数据条数
    // nTotal 处理数据总条数
    // n 当前一轮多少个,每次批量写入时清0
    total, nTotal, n, eof := 0, 0, 0, false
    for {
        //line, _, err := scanner.ReadLine()
        line, err := scanner.ReadBytes('\n')
        if err != nil {
            if err == io.EOF {
                eof = true
            } else {
                fmt.Println(err.Error())
                break
            }
        }
        total++

        if len(line) == 0 {
            //errMsg := list[len(list)-1].ID + "下一行错误,数据为空"
            errMsg := fmt.Sprintf("数据为空:%s  line:%d err:%v \n", string(line), total, err)
            utils.LogDebugWithPath("log", "GKDataImport", errMsg+":"+string(line))
            errDataIds = append(errDataIds, errMsg)
        } else if len(line) != 0 && json.Valid(line) {
            var ds = saveGongKongData{}
            err = json.Unmarshal(line, &ds)
            if err != nil {
                errMsg := list[len(list)-1].ID + "下一行错误,json.Unmarshal fail err: " + err.Error()
                errDataIds = append(errDataIds, errMsg)
                errMsgSave := fmt.Sprintf("import data file: %s failed, err: %s \n", path.Base(filePath), err.Error())
                log.Println(errMsgSave)
                utils.LogDebugWithPath("log", "GKDataImport", errMsgSave)
                break
            }
            list = append(list, ds)
        } else {
            errMsg := fmt.Sprintf("数据其它错误:%s  line:%d err:%v \n", string(line), total, err)
            utils.LogDebugWithPath("log", "GKDataImport", errMsg+":"+string(line))
            errDataIds = append(errDataIds, errMsg)
        }

        n++
        if n == 1000 || eof {
            nTotal += len(list)
            log.Printf("已经读取 %d 条, 已处理处理 %d 条数据", total, nTotal)
            n = 0
            if err = CreateImportByBulk(&list); err != nil {
                break
            }
            if eof {
                break
            }
            list = list[0:0]
        }
    }

    if err != nil {
        fmt.Printf("import dns file: %s failed, err: %s", path.Base(filePath), err.Error())
        return
    }
    log.Println("===============================================>")
    msg := fmt.Sprintf("共计 %d 条数据  处理完成 %d 条数据 ,错误 %d 条 errDataIds:%v file:%s \n", total, nTotal, total-nTotal, errDataIds, filePath)
    log.Println(msg)
    utils.LogDebugWithPath("log/exportEs", "exportEs"+config.CONFIG.EsClient.IndexName, msg)
    return
}


func CreateImportByBulk(list *[]saveGongKongData) error {

    req := es.EsClient.Bulk().Index(config.CONFIG.EsClient.IndexName).
        Type("service") //es6需要指定tpye  es7 不需要
    for _, item := range *list {
        doc := elastic.NewBulkIndexRequest().
            Id(item.ID).
            Doc(item.Source)
        req.Add(doc)
    }
    actions := req.NumberOfActions()
    if actions <= 0 {
        return fmt.Errorf("req.NumberOfActions < 0 ,list:%v", list)
    }
    bResp, err := req.Refresh("true").Do(context.Background())
    if err != nil {
        log.Printf("CreateImportByBulk fail err:%v", err)
    }
    var success = make([]string, 0)
    type failedDetail struct {
        Ids         []string
        ErrorMagmap map[string]string
    }
    var fDetail failedDetail
    // 统计结果
    for _, v := range bResp.Items {
        var item = *v["index"]
        //if v["index"].Status == 201 {
        //    fmt.Printf("k--->:%#v , status:%#v  err:%v  v:%#v \n ", k, v["index"].Status, item.Error, v["index"])
        //}
        if item.Error == nil {
            success = append(success, item.Id)
        } else {
            fDetail.Ids = append(fDetail.Ids, item.Id)
            b, _ := json.Marshal(item.Error)
            fDetail.ErrorMagmap = make(map[string]string, 0)
            fDetail.ErrorMagmap[item.Id] = string(b)
        }
    }
    //responseMsg := fmt.Sprintf("处理条数: %d 条 , 成功: %d 条, 失败 %d 条.", len(*list), len(success), len(fDetail.Ids))
    //fmt.Println("responseMsg:", responseMsg)
    return err
}

json字符串转为map

content = `
{"openDns":1,"taskType":2,"isWait":1,"copyTargets":"static/downloads/1.xlsx","targetGroups":null,"targets":["static/downloads/1.xlsx"],"timeout":30,"domain":true,"subDomain":false,"ipicp":false,"whois":false,"probeTarget":1,"icpQueryMaxNum":100,"nodeIDList":"","dnsServer":"114.114.114.114","filePath":"static/downloads/1.xlsx"}
`
mapData := make(map[string]interface{})
if err = json.Unmarshal(content, &mapData); err != nil {
        return
}

清空切片

package main

import "fmt"

func main() {
    var names = []string{"lisi", "wangwu", "zhangsan"}
    fmt.Println("name1:", names) //name1: [lisi wangwu zhangsan]
    names = RemoveIndex(names, 0)
    fmt.Println("name2:", names) //name2: [wangwu zhangsan]

    //通过输出,我们很容易得到如下结论:
    //通过切片表达式清空切片,仅长度归0,而容量维持不变
    //解决了可能扩容的问题
    //清空后,切片指向的底层数组也不变
    //解决了更换底层数组,开辟新空间,以及可能的垃圾回收问题
    //注意:切片指向的底层数组不变,也就导致了无论是通过切片操作还是数组操作,都会影响彼此。
    //如果仅仅是清空切片,后续继续 append 操作,博主更推荐切片表达式的方法[0:0] 。
    // 原文:https://blog.csdn.net/m0_70556273/article/details/127077579
    names = names[0:0]
    fmt.Println("name3:", names) //name3: []

}
func RemoveIndex(s []string, index int) []string {
    return append(s[:index], s[index+1:]...)
}

Golang 切片/数组实现分页

func SlicePage(page, pageSize, nums int64) (sliceStart, sliceEnd int64) {
    if page <= 0 {
        page = 1
    }
    if pageSize < 0 {
        pageSize = 20 //设置一页默认显示的记录数
    }
    if pageSize > nums {
        return 0, nums
    }
    // 总页数
    pageCount := int64(math.Ceil(float64(nums) / float64(pageSize)))
    if page > pageCount {
        return 0, 0
    }
    sliceStart = (page - 1) * pageSize
    sliceEnd = sliceStart + pageSize

    if sliceEnd > nums {
        sliceEnd = nums
    }
    return sliceStart, sliceEnd
}

测试:

func main() {
    var data = []string{"qww", "dsassa", "1313", "jasdd", "dsawdqw"}
    start, end := SlicePage(1, 3, int64(len(data))) //第一页1页显示3条数据
    afterLimitData := data[start:end]               //分页后的数据
    fmt.Println("分页后的数据:", afterLimitData)
    fmt.Println("数据总量:", len(data))
}

结果


 分页后的数据: ["qww", "dsassa", "1313"]
 数据总量:5

// 去前缀
func FormatResult(res []byte) (string, error) {
    trimKeyPrefix, err := TrimKeyPrefixToString(string(res), consts.ColPrefix, []string{})
    if err != nil {
        return "", err
    }
    jsonStrTmp, err := gjson.DecodeToJson(trimKeyPrefix)
    if err != nil {
        return "", err
    }
    if jsonStrTmp.Contains("hits") {
        return jsonStrTmp.Get("hits.hits").String(), nil

    }
    return jsonStrTmp.MustToJsonString(), nil
}

// TrimKeyPrefixToMap 给 map 去除 key 前缀
// dataStr    数据源 map
// prefix  要删除的前缀
// ignores 排除的字段
func TrimKeyPrefixToString(dataStr, prefix string, ignores []string) (string, error) {
    if len(prefix) == 0 {
        return dataStr, nil
    }
    var dataMap = make(map[string]interface{})
    var targetMap = make(map[string]interface{})

    err := json.Unmarshal([]byte(dataStr), &dataMap)
    if err != nil {
        return "", err
    }
    toMap := TrimKeyPrefixToMap(dataMap, targetMap, prefix, ignores...)
    marshal, err := json.Marshal(toMap)
    if err != nil {
        return "", err
    }
    return string(marshal), nil
}




// AddKeyPrefixToMap 给 map 添加 key 前缀
// data    数据源 map
// target  目标   map
// prefix  要添加的前缀
// ignores 排除的字段
func AddKeyPrefixToMap(data, target map[string]interface{}, prefix string, ignores ...string) map[string]interface{} {
    passMap := make(map[string]struct{})
    for _, ig := range ignores {
        passMap[ig] = struct{}{}
    }
    for k, m := range data {
        if m == nil {
            continue
        }
        _, pass := passMap[k]
        mType := reflect.TypeOf(m)
        mValue := reflect.ValueOf(m)
        var d interface{}
        if mType.Kind() == reflect.Map {
            m1 := m.(map[string]interface{})
            var subTarget = make(map[string]interface{})
            subTarget = AddKeyPrefixToMap(m1, subTarget, prefix, ignores...)
            d = subTarget
        } else if mType.Kind() == reflect.Slice {
            l := mValue.Len()
            arr := make([]interface{}, 0, l)
            for i := 0; i < l; i++ {
                value := mValue.Index(i) // Value of item
                itemType := value.Type() // Type of item
                switch itemType.Kind() {
                case reflect.Map:
                    // 递归加前缀
                    m2 := value.Interface().(map[string]interface{})
                    var subTarget = make(map[string]interface{})
                    subTarget = AddKeyPrefixToMap(m2, subTarget, prefix, ignores...)
                    arr = append(arr, subTarget)
                case reflect.Interface:
                    val := value.Interface()
                    if m2, ok := val.(map[string]interface{}); ok {
                        var subTarget = make(map[string]interface{})
                        subTarget = AddKeyPrefixToMap(m2, subTarget, prefix, ignores...)
                        arr = append(arr, subTarget)
                    } else {
                        arr = append(arr, val)
                    }
                case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
                    arr = append(arr, value.Int())
                case reflect.String:
                    arr = append(arr, value.String())
                case reflect.Bool:
                    arr = append(arr, value.Bool())
                case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
                    arr = append(arr, value.Uint())
                default:
                    continue
                }
            }
            d = arr
        } else {
            d = m
        }
        if pass {
            target[k] = d
        } else {
            target[prefix+k] = d
        }
    }
    return target
}

// TrimKeyPrefixToMap 给 map 去除 key 前缀
// data    数据源 map
// target  目标   map
// prefix  要删除的前缀
// ignores 排除的字段
func TrimKeyPrefixToMap(data, target map[string]interface{}, prefix string, ignores ...string) map[string]interface{} {
    passMap := make(map[string]struct{})
    for _, ig := range ignores {
        passMap[ig] = struct{}{}
    }
    for k, m := range data {
        if m == nil {
            continue
        }
        _, pass := passMap[k]
        mType := reflect.TypeOf(m)
        mValue := reflect.ValueOf(m)
        var d interface{}
        if mType.Kind() == reflect.Map {
            m1 := m.(map[string]interface{})
            var subTarget = make(map[string]interface{})
            subTarget = TrimKeyPrefixToMap(m1, subTarget, prefix, ignores...)
            d = subTarget
        } else if mType.Kind() == reflect.Slice {
            l := mValue.Len()
            arr := make([]interface{}, 0, l)
            for i := 0; i < l; i++ {
                value := mValue.Index(i) // Value of item
                itemType := value.Type() // Type of item
                switch itemType.Kind() {
                case reflect.Map:
                    // 递归去前缀
                    m2 := value.Interface().(map[string]interface{})
                    var subTarget = make(map[string]interface{})
                    subTarget = TrimKeyPrefixToMap(m2, subTarget, prefix, ignores...)
                    arr = append(arr, subTarget)
                case reflect.Interface:
                    val := value.Interface()
                    if m2, ok := val.(map[string]interface{}); ok {
                        var subTarget = make(map[string]interface{})
                        subTarget = TrimKeyPrefixToMap(m2, subTarget, prefix, ignores...)
                        arr = append(arr, subTarget)
                    } else {
                        arr = append(arr, val)
                    }
                case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
                    arr = append(arr, value.Int())
                case reflect.String:
                    arr = append(arr, value.String())
                case reflect.Bool:
                    arr = append(arr, value.Bool())
                case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
                    arr = append(arr, value.Uint())
                default:
                    continue
                }
            }
            d = arr
        } else {
            d = m
        }
        if pass {
            target[k] = d
        } else {
            target[strings.TrimPrefix(k, prefix)] = d
        }
    }
    return target
}

输出结果:

func TestFormatResult(t *testing.T) {
    //type args struct {
    //    res []byte
    //}

    type args struct {
        dataStr []byte
        prefix  string
        ignores []string
    }
    dataStrData := `{"_id":"https://www.badgerfarmacolbridgeclub.co.uk","_index":"wa_zdzc_db_t_fofapro_subdomain_cert","_source":{"c_favicon":{"base64":"R0lGODdhlgCWAOcAAAQCBCyCLJ6EWs/LIYsGDJyNcZzGlNrCkqKkk0FCGd7iw5xEENCklTR+NN/Jvezy08yEeEQIBOhIQM20h1REKKalniMkH/kCBO7RvvXlyFpXNqKUdNzVsmRiGGRkXOIkItbYxLK0pOu0nodrN8RwZHN0aOjm4M2Vh3zKfHyCFLRi","c_url":"https://www.badgerfarmacolbridgeclub.co.uk/wp-content/uploads/2019/05/Logocards-150x150.gif"},"c_lastupdatetime":"2023-09-26 09:47:03"},"_type":"_doc","sort":[1695721623000]}`
    wantDataStrData := `{"_id":"https://www.badgerfarmacolbridgeclub.co.uk","_index":"wa_zdzc_db_t_fofapro_subdomain_cert","_source":{"favicon":{"base64":"R0lGODdhlgCWAOcAAAQCBCyCLJ6EWs/LIYsGDJyNcZzGlNrCkqKkk0FCGd7iw5xEENCklTR+NN/Jvezy08yEeEQIBOhIQM20h1REKKalniMkH/kCBO7RvvXlyFpXNqKUdNzVsmRiGGRkXOIkItbYxLK0pOu0nodrN8RwZHN0aOjm4M2Vh3zKfHyCFLRi","url":"https://www.badgerfarmacolbridgeclub.co.uk/wp-content/uploads/2019/05/Logocards-150x150.gif"},"lastupdatetime":"2023-09-26 09:47:03"},"_type":"_doc","sort":[1695721623000]}`

    tests := []struct {
        name    string
        args    args
        want    string
        wantErr assert.ErrorAssertionFunc
    }{
        // TODO: Add test cases.
        {
            name: "TestTrimKeyPrefixToString",
            args: args{
                dataStr: []byte(dataStrData),
                prefix:  "c_",
                ignores: []string{},
            },
            want: wantDataStrData,
        },
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got, err := FormatResult(tt.args.dataStr)
            //if !tt.wantErr(t, err, fmt.Sprintf("FormatResult(%v)", tt.want)) {
            //    return
            //}
            assert.NoError(t, err)
            //assert.Contains(t, res, tt.want)
            assert.Equalf(t, tt.want, got, "FormatResult(%v)", tt.want)
        })
    }
}

数组分组

// []string{"1", "2", "3", "4", "5", "6"} -> 如果N=2,则返回   [][]string{{"1", "2", "3"}, {"4", "5", "6"}}
// SplitIntoGroups 根据指定的大小拆分切片
func SplitIntoGroups[T any](arr []T, N int) [][]T {
    var result [][]T
    for i := 0; i < len(arr); i += N {
        end := i + N
        if end > len(arr) {
            end = len(arr)
        }
        result = append(result, arr[i:end])
    }
    return result
}
作者:admin  创建时间:2020-04-02 14:11
最后编辑:海马  更新时间:2024-12-22 19:32