Golang 深拷贝

  1. 深拷贝

    1
    拷贝的是数据本身,创造一个新对象,新创建的对象与原对象不共享内存,新创建的对象在内存中开辟一个新的内存地址,新对象值修改时不会影响原对象值
  2. 浅拷贝

    1
    浅拷贝:拷贝的是数据地址,只复制指向的对象的指针,此时新对象和老对象指向的内存地址是一样的,新对象值修改时老对象也会变化
  1. Go实现
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    func DeepCopy(data interface{}) interface{} {
    dataType := reflect.TypeOf(data)
    dataValue := reflect.ValueOf(data)
    // 如果是指针类型,获取指针指向的值
    if dataType.Kind() == reflect.Ptr {
    dataType = dataType.Elem()
    dataValue = dataValue.Elem()
    }
    switch dataType.Kind() {
    case reflect.Map:
    copied := reflect.MakeMap(dataType)
    mapKeys := dataValue.MapKeys()
    for _, key := range mapKeys {
    value := dataValue.MapIndex(key)
    copiedValue := DeepCopy(value.Interface())
    // 这步大部分情况下如需考虑,因为基本没人会使用引用类型的key
    copiedKey := reflect.ValueOf(DeepCopy(key.Interface()))
    copied.SetMapIndex(copiedKey, reflect.ValueOf(copiedValue))
    }
    return copied.Interface()
    case reflect.Slice:
    copied := reflect.MakeSlice(dataType, dataValue.Len(), dataValue.Len())
    for i := 0; i < dataValue.Len(); i++ {
    element := dataValue.Index(i)
    copiedElement := DeepCopy(element.Interface())
    copied.Index(i).Set(reflect.ValueOf(copiedElement))
    }
    return copied.Interface()
    case reflect.Struct:
    copied := reflect.New(dataType).Elem()
    for i := 0; i < dataType.NumField(); i++ {
    fieldType := dataType.Field(i)
    fieldValue := dataValue.Field(i)
    // 如果字段是可导出的(大写开头),则进行深拷贝
    if fieldType.PkgPath == "" {
    copiedField := DeepCopy(fieldValue.Interface())
    copied.Field(i).Set(reflect.ValueOf(copiedField))
    }
    }
    return copied.Interface()
    default:
    return data
    }
    }
-------------本文结束感谢您的阅读-------------
分享不易,请我喝杯咖啡吧~~~