最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go中GoFrameMap轉(zhuǎn)換詳解

 更新時(shí)間:2026年05月18日 08:41:26   作者:念何架構(gòu)之路  
本文詳細(xì)解析了Go語言中g(shù)conv.Map()方法的實(shí)現(xiàn)原理,該方法通過遞歸處理將各種數(shù)據(jù)類型轉(zhuǎn)換為map[string]any格式,感興趣的可以了解一下

示例:

package main
import (
    "github.com/gogf/gf/v2/frame/g"
    "github.com/gogf/gf/v2/util/gconv"
)
func main() {
    type User struct {
       Uid  string `c:"uid"`
       Name string `c:"name"`
    }
    //對象.
    g.Dump(gconv.Map(User{Uid: "1", Name: "john"}))
}

輸出結(jié)果:

gconv.Map()方法:

func Map(value any, option ...MapOption) map[string]any {
    result, _ := defaultConverter.Map(value, getUsedMapOption(option...))
    return result
}

因?yàn)檎{(diào)用沒有傳入這個值.然后通過斷點(diǎn)驗(yàn)證可以知道option為nil.

getUsedMapOption()方法:

func getUsedMapOption(option ...MapOption) MapOption {
    var usedOption = MapOption{
       ContinueOnError: true,
    }
    if len(option) > 0 {
       usedOption = option[0]
    }
    return usedOption
}

defaultConverter.Map()方法:

func (c *Converter) Map(value any, option ...MapOption) (map[string]any, error) {
    return c.doMapConvert(value, RecursiveTypeAuto, false, c.getMapOption(option...))
}

RecursiveTypeAuto的值提前定義好的.

c.doMapConvert()方法:

func (c *Converter) doMapConvert(
    value any, recursive RecursiveType, mustMapReturn bool, option MapOption,
) (map[string]any, error) {
    if value == nil {
       return nil, nil
    }
    // It redirects to its underlying value if it has implemented interface iVal.
    if v, ok := value.(localinterface.IVal); ok {
       value = v.Val()
    }
    var (
       err     error
       newTags = gtag.StructTagPriority
    )
    if option.Deep {
       recursive = RecursiveTypeTrue
    }
    switch len(option.Tags) {
    case 0:
       // No need handling.
    case 1:
       newTags = append(strings.Split(option.Tags[0], ","), gtag.StructTagPriority...)
    default:
       newTags = append(option.Tags, gtag.StructTagPriority...)
    }
    // Assert the common combination of types, and finally it uses reflection.
    dataMap := make(map[string]any)
    switch r := value.(type) {
    case string:
       // If it is a JSON string, automatically unmarshal it!
       if len(r) > 0 && r[0] == '{' && r[len(r)-1] == '}' {
          if err = json.UnmarshalUseNumber([]byte(r), &dataMap); err != nil {
             return nil, err
          }
       } else {
          return nil, nil
       }
    case []byte:
       // If it is a JSON string, automatically unmarshal it!
       if len(r) > 0 && r[0] == '{' && r[len(r)-1] == '}' {
          if err = json.UnmarshalUseNumber(r, &dataMap); err != nil {
             return nil, err
          }
       } else {
          return nil, nil
       }
    case map[any]any:
       recursiveOption := option
       recursiveOption.Tags = newTags
       for k, v := range r {
          s, err := c.String(k)
          if err != nil && !option.ContinueOnError {
             return nil, err
          }
          dataMap[s], err = c.doMapConvertForMapOrStructValue(
             doMapConvertForMapOrStructValueInput{
                IsRoot:          false,
                Value:           v,
                RecursiveType:   recursive,
                RecursiveOption: recursive == RecursiveTypeTrue,
                Option:          recursiveOption,
             },
          )
          if err != nil && !option.ContinueOnError {
             return nil, err
          }
       }
    case map[any]string:
       for k, v := range r {
          s, err := c.String(k)
          if err != nil && !option.ContinueOnError {
             return nil, err
          }
          dataMap[s] = v
       }
    case map[any]int:
       for k, v := range r {
          s, err := c.String(k)
          if err != nil && !option.ContinueOnError {
             return nil, err
          }
          dataMap[s] = v
       }
    case map[any]uint:
       for k, v := range r {
          s, err := c.String(k)
          if err != nil && !option.ContinueOnError {
             return nil, err
          }
          dataMap[s] = v
       }
    case map[any]float32:
       for k, v := range r {
          s, err := c.String(k)
          if err != nil && !option.ContinueOnError {
             return nil, err
          }
          dataMap[s] = v
       }
    case map[any]float64:
       for k, v := range r {
          s, err := c.String(k)
          if err != nil && !option.ContinueOnError {
             return nil, err
          }
          dataMap[s] = v
       }
    case map[string]bool:
       for k, v := range r {
          dataMap[k] = v
       }
    case map[string]int:
       for k, v := range r {
          dataMap[k] = v
       }
    case map[string]uint:
       for k, v := range r {
          dataMap[k] = v
       }
    case map[string]float32:
       for k, v := range r {
          dataMap[k] = v
       }
    case map[string]float64:
       for k, v := range r {
          dataMap[k] = v
       }
    case map[string]string:
       for k, v := range r {
          dataMap[k] = v
       }
    case map[string]any:
       if recursive == RecursiveTypeTrue {
          recursiveOption := option
          recursiveOption.Tags = newTags
          // A copy of current map.
          for k, v := range r {
             dataMap[k], err = c.doMapConvertForMapOrStructValue(
                doMapConvertForMapOrStructValueInput{
                   IsRoot:          false,
                   Value:           v,
                   RecursiveType:   recursive,
                   RecursiveOption: recursive == RecursiveTypeTrue,
                   Option:          recursiveOption,
                },
             )
             if err != nil && !option.ContinueOnError {
                return nil, err
             }
          }
       } else {
          // It returns the map directly without any changing.
          return r, nil
       }
    case map[int]any:
       recursiveOption := option
       recursiveOption.Tags = newTags
       for k, v := range r {
          s, err := c.String(k)
          if err != nil && !option.ContinueOnError {
             return nil, err
          }
          dataMap[s], err = c.doMapConvertForMapOrStructValue(
             doMapConvertForMapOrStructValueInput{
                IsRoot:          false,
                Value:           v,
                RecursiveType:   recursive,
                RecursiveOption: recursive == RecursiveTypeTrue,
                Option:          recursiveOption,
             },
          )
          if err != nil && !option.ContinueOnError {
             return nil, err
          }
       }
    case map[int]string:
       for k, v := range r {
          s, err := c.String(k)
          if err != nil && !option.ContinueOnError {
             return nil, err
          }
          dataMap[s] = v
       }
    case map[uint]string:
       for k, v := range r {
          s, err := c.String(k)
          if err != nil && !option.ContinueOnError {
             return nil, err
          }
          dataMap[s] = v
       }

    default:
       // Not a common type, it then uses reflection for conversion.
       var reflectValue reflect.Value
       if v, ok := value.(reflect.Value); ok {
          reflectValue = v
       } else {
          reflectValue = reflect.ValueOf(value)
       }
       reflectKind := reflectValue.Kind()
       // If it is a pointer, we should find its real data type.
       for reflectKind == reflect.Pointer {
          reflectValue = reflectValue.Elem()
          reflectKind = reflectValue.Kind()
       }
       switch reflectKind {
       // If `value` is type of array, it converts the value of even number index as its key and
       // the value of odd number index as its corresponding value, for example:
       // []string{"k1","v1","k2","v2"} => map[string]any{"k1":"v1", "k2":"v2"}
       // []string{"k1","v1","k2"}      => map[string]any{"k1":"v1", "k2":nil}
       case reflect.Slice, reflect.Array:
          length := reflectValue.Len()
          for i := 0; i < length; i += 2 {
             s, err := c.String(reflectValue.Index(i).Interface())
             if err != nil && !option.ContinueOnError {
                return nil, err
             }
             if i+1 < length {
                dataMap[s] = reflectValue.Index(i + 1).Interface()
             } else {
                dataMap[s] = nil
             }
          }
       case reflect.Map, reflect.Struct, reflect.Interface:
          recursiveOption := option
          recursiveOption.Tags = newTags
          convertedValue, err := c.doMapConvertForMapOrStructValue(
             doMapConvertForMapOrStructValueInput{
                IsRoot:          true,
                Value:           value,
                RecursiveType:   recursive,
                RecursiveOption: recursive == RecursiveTypeTrue,
                Option:          recursiveOption,
                MustMapReturn:   mustMapReturn,
             },
          )
          if err != nil && !option.ContinueOnError {
             return nil, err
          }
          if m, ok := convertedValue.(map[string]any); ok {
             return m, nil
          }
          return nil, nil
       default:
          return nil, nil
       }
    }
    return dataMap, nil
}

gtag.StructTagPriority:

var StructTagPriority = []string{
    GConv, Param, GConvShort, ParamShort, Json,
}

MapOption結(jié)構(gòu)體:

type MapOption struct {
    // Deep marks doing Map function recursively, which means if the attribute of given converting value
    // is also a struct/*struct, it automatically calls Map function on this attribute converting it to
    // a map[string]any type variable.
    Deep bool

    // OmitEmpty ignores the attributes that has json `omitempty` tag.
    OmitEmpty bool

    // Tags specifies the converted map key name by struct tag name.
    Tags []string

    // ContinueOnError specifies whether to continue converting the next element
    // if one element converting fails.
    ContinueOnError bool
}

上面獲取這個結(jié)構(gòu)體的時(shí)候.因?yàn)闆]有給Deep賦值.所以這里都默認(rèn)為false.所以recursive還是auto.

反射處理默認(rèn)分支.

首先將 value 轉(zhuǎn)為 reflect.Value(若已是 reflect.Value 則直接使用)。

引用指針,直到得到非指針的 reflectValue 和 reflectKind。

根據(jù) reflectKind 分情況:reflect.Slice 或 reflect.Array
將數(shù)組/切片視為鍵值交替的序列:

偶數(shù)索引為鍵,奇數(shù)索引為值(例如 ["k1","v1","k2","v2"] → {"k1":"v1","k2":"v2"})。

若長度為奇數(shù),最后一個鍵對應(yīng)的值為 nil。

每個鍵通過 c.String() 轉(zhuǎn)換為字符串,若出錯且不忽略錯誤則返回。

reflect.Map、reflect.Struct、reflect.Interface
調(diào)用 c.doMapConvertForMapOrStructValue 進(jìn)行轉(zhuǎn)換,該函數(shù)會遞歸處理 map/struct,并根據(jù) recursive 和 MustMapReturn 決定最終輸出。

若返回的值確實(shí)是 map[string]any,則返回它;否則返回 nil, nil。

其他類型
直接返回 nil, nil,不進(jìn)行轉(zhuǎn)換。

doMapConvertForMapOrStructValue()方法:

func (c *Converter) doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) (any, error) {
    if !in.IsRoot && !in.RecursiveOption {
       return in.Value, nil
    }
    var (
       err          error
       reflectValue reflect.Value
    )
    if v, ok := in.Value.(reflect.Value); ok {
       reflectValue = v
       in.Value = v.Interface()
    } else {
       reflectValue = reflect.ValueOf(in.Value)
    }
    reflectKind := reflectValue.Kind()
    // If it is a pointer, we should find its real data type.
    for reflectKind == reflect.Pointer {
       reflectValue = reflectValue.Elem()
       reflectKind = reflectValue.Kind()
    }
    switch reflectKind {
    case reflect.Map:
       var (
          mapIter = reflectValue.MapRange()
          dataMap = make(map[string]any)
       )
       for mapIter.Next() {
          var (
             mapKeyValue = mapIter.Value()
             mapValue    any
          )
          switch {
          case mapKeyValue.IsZero():
             if utils.CanCallIsNil(mapKeyValue) && mapKeyValue.IsNil() {
                // quick check for nil value.
                mapValue = nil
             } else {
                // in case of:
                // exception recovered: reflect: call of reflect.Value.Interface on zero Value
                mapValue = reflect.New(mapKeyValue.Type()).Elem().Interface()
             }
          default:
             mapValue = mapKeyValue.Interface()
          }
          s, err := c.String(mapIter.Key().Interface())
          if err != nil && !in.Option.ContinueOnError {
             return nil, err
          }
          dataMap[s], err = c.doMapConvertForMapOrStructValue(
             doMapConvertForMapOrStructValueInput{
                IsRoot:          false,
                Value:           mapValue,
                RecursiveType:   in.RecursiveType,
                RecursiveOption: in.RecursiveType == RecursiveTypeTrue,
                Option:          in.Option,
             },
          )
          if err != nil && !in.Option.ContinueOnError {
             return nil, err
          }
       }
       return dataMap, nil
    case reflect.Struct:
       var dataMap = make(map[string]any)
       // Map converting interface check.
       if v, ok := in.Value.(localinterface.IMapStrAny); ok {
          // Value copy, in case of concurrent safety.
          for mapK, mapV := range v.MapStrAny() {
             if in.RecursiveOption {
                dataMap[mapK], err = c.doMapConvertForMapOrStructValue(
                   doMapConvertForMapOrStructValueInput{
                      IsRoot:          false,
                      Value:           mapV,
                      RecursiveType:   in.RecursiveType,
                      RecursiveOption: in.RecursiveType == RecursiveTypeTrue,
                      Option:          in.Option,
                   },
                )
                if err != nil && !in.Option.ContinueOnError {
                   return nil, err
                }
             } else {
                dataMap[mapK] = mapV
             }
          }
          if len(dataMap) > 0 {
             return dataMap, nil
          }
       }
       // Using reflect for converting.
       var (
          rtField     reflect.StructField
          rvField     reflect.Value
          reflectType = reflectValue.Type() // attribute value type.
          mapKey      = ""                  // mapKey may be the tag name or the struct attribute name.
       )
       for i := 0; i < reflectValue.NumField(); i++ {
          rtField = reflectType.Field(i)
          rvField = reflectValue.Field(i)
          // Only convert the public attributes.
          fieldName := rtField.Name
          if !utils.IsLetterUpper(fieldName[0]) {
             continue
          }
          mapKey = ""
          fieldTag := rtField.Tag
          for _, tag := range in.Option.Tags {
             if mapKey = fieldTag.Get(tag); mapKey != "" {
                break
             }
          }
          if mapKey == "" {
             mapKey = fieldName
          } else {
             // Support json tag feature: -, omitempty
             mapKey = strings.TrimSpace(mapKey)
             if mapKey == "-" {
                continue
             }
             array := strings.Split(mapKey, ",")
             if len(array) > 1 {
                switch strings.TrimSpace(array[1]) {
                case "omitempty":
                   if in.Option.OmitEmpty && empty.IsEmpty(rvField.Interface()) {
                      continue
                   } else {
                      mapKey = strings.TrimSpace(array[0])
                   }
                default:
                   mapKey = strings.TrimSpace(array[0])
                }
             }
             if mapKey == "" {
                mapKey = fieldName
             }
          }
          if in.RecursiveOption || rtField.Anonymous {
             // Do map converting recursively.
             var (
                rvAttrField = rvField
                rvAttrKind  = rvField.Kind()
             )
             if rvAttrKind == reflect.Pointer {
                rvAttrField = rvField.Elem()
                rvAttrKind = rvAttrField.Kind()
             }
             switch rvAttrKind {
             case reflect.Struct:
                // Embedded struct and has no fields, just ignores it.
                // Eg: gmeta.Meta
                if rvAttrField.Type().NumField() == 0 {
                   continue
                }
                var (
                   hasNoTag = mapKey == fieldName
                   // DO NOT use rvAttrField.Interface() here,
                   // as it might be changed from pointer to struct.
                   rvInterface = rvField.Interface()
                )
                switch {
                case hasNoTag && rtField.Anonymous:
                   // It means this attribute field has no tag.
                   // Overwrite the attribute with sub-struct attribute fields.
                   anonymousValue, err := c.doMapConvertForMapOrStructValue(
                      doMapConvertForMapOrStructValueInput{
                         IsRoot:          false,
                         Value:           rvInterface,
                         RecursiveType:   in.RecursiveType,
                         RecursiveOption: true,
                         Option:          in.Option,
                      },
                   )
                   if err != nil && !in.Option.ContinueOnError {
                      return nil, err
                   }
                   if m, ok := anonymousValue.(map[string]any); ok {
                      for k, v := range m {
                         dataMap[k] = v
                      }
                   } else {
                      dataMap[mapKey] = rvInterface
                   }
                // It means this attribute field has desired tag.
                case !hasNoTag && rtField.Anonymous:
                   dataMap[mapKey], err = c.doMapConvertForMapOrStructValue(
                      doMapConvertForMapOrStructValueInput{
                         IsRoot:          false,
                         Value:           rvInterface,
                         RecursiveType:   in.RecursiveType,
                         RecursiveOption: true,
                         Option:          in.Option,
                      },
                   )
                   if err != nil && !in.Option.ContinueOnError {
                      return nil, err
                   }
                default:
                   dataMap[mapKey], err = c.doMapConvertForMapOrStructValue(
                      doMapConvertForMapOrStructValueInput{
                         IsRoot:          false,
                         Value:           rvInterface,
                         RecursiveType:   in.RecursiveType,
                         RecursiveOption: in.RecursiveType == RecursiveTypeTrue,
                         Option:          in.Option,
                      },
                   )
                   if err != nil && !in.Option.ContinueOnError {
                      return nil, err
                   }
                }
             // The struct attribute is type of slice.
             case reflect.Array, reflect.Slice:
                length := rvAttrField.Len()
                if length == 0 {
                   dataMap[mapKey] = rvAttrField.Interface()
                   break
                }
                array := make([]any, length)
                for arrayIndex := 0; arrayIndex < length; arrayIndex++ {
                   array[arrayIndex], err = c.doMapConvertForMapOrStructValue(
                      doMapConvertForMapOrStructValueInput{
                         IsRoot:          false,
                         Value:           rvAttrField.Index(arrayIndex).Interface(),
                         RecursiveType:   in.RecursiveType,
                         RecursiveOption: in.RecursiveType == RecursiveTypeTrue,
                         Option:          in.Option,
                      },
                   )
                   if err != nil && !in.Option.ContinueOnError {
                      return nil, err
                   }
                }
                dataMap[mapKey] = array
             case reflect.Map:
                var (
                   mapIter   = rvAttrField.MapRange()
                   nestedMap = make(map[string]any)
                )
                for mapIter.Next() {
                   s, err := c.String(mapIter.Key().Interface())
                   if err != nil && !in.Option.ContinueOnError {
                      return nil, err
                   }
                   nestedMap[s], err = c.doMapConvertForMapOrStructValue(
                      doMapConvertForMapOrStructValueInput{
                         IsRoot:          false,
                         Value:           mapIter.Value().Interface(),
                         RecursiveType:   in.RecursiveType,
                         RecursiveOption: in.RecursiveType == RecursiveTypeTrue,
                         Option:          in.Option,
                      },
                   )
                   if err != nil && !in.Option.ContinueOnError {
                      return nil, err
                   }
                }
                dataMap[mapKey] = nestedMap
             default:
                if rvField.IsValid() {
                   dataMap[mapKey] = reflectValue.Field(i).Interface()
                } else {
                   dataMap[mapKey] = nil
                }
             }
          } else {
             // No recursive map value converting
             if rvField.IsValid() {
                dataMap[mapKey] = reflectValue.Field(i).Interface()
             } else {
                dataMap[mapKey] = nil
             }
          }
       }
       if !in.MustMapReturn && len(dataMap) == 0 {
          return in.Value, nil
       }
       return dataMap, nil
    // The given value is type of slice.
    case reflect.Array, reflect.Slice:
       length := reflectValue.Len()
       if length == 0 {
          break
       }
       array := make([]any, reflectValue.Len())
       for i := 0; i < length; i++ {
          array[i], err = c.doMapConvertForMapOrStructValue(doMapConvertForMapOrStructValueInput{
             IsRoot:          false,
             Value:           reflectValue.Index(i).Interface(),
             RecursiveType:   in.RecursiveType,
             RecursiveOption: in.RecursiveType == RecursiveTypeTrue,
             Option:          in.Option,
          })
          if err != nil && !in.Option.ContinueOnError {
             return nil, err
          }
       }
       return array, nil
    default:
    }
    return in.Value, nil
}

下面又會對值進(jìn)行各種類型的判斷轉(zhuǎn)換.可以參考上面的.

到此這篇關(guān)于Go中GoFrameMap轉(zhuǎn)換詳解的文章就介紹到這了,更多相關(guān)GoFrameMap轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang?MySQL實(shí)現(xiàn)對數(shù)據(jù)庫表存儲獲取操作示例

    golang?MySQL實(shí)現(xiàn)對數(shù)據(jù)庫表存儲獲取操作示例

    這篇文章主要為大家介紹了golang?MySQL實(shí)現(xiàn)對數(shù)據(jù)庫表存儲獲取操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • grpc-go如何通過context傳遞額外數(shù)據(jù)

    grpc-go如何通過context傳遞額外數(shù)據(jù)

    metadata是grpc內(nèi)置的,用RPC服務(wù)傳遞http頭數(shù)據(jù),分in和out兩種,對應(yīng)的key都為一個空struct,這篇文章主要介紹了grpc-go通過context傳遞額外數(shù)據(jù),需要的朋友可以參考下
    2024-02-02
  • Go語言滑動窗口最大值的實(shí)現(xiàn)示例

    Go語言滑動窗口最大值的實(shí)現(xiàn)示例

    本文主要介紹了Go語言滑動窗口最大值的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-08-08
  • Golang基于文件魔數(shù)判斷文件類型的案例代碼

    Golang基于文件魔數(shù)判斷文件類型的案例代碼

    這篇文章主要介紹了Golang基于文件魔數(shù)判斷文件類型,本文介紹了基于文件魔數(shù)判斷文件類型的方法,主要涉及如何ReadSeek讀取文件指定字節(jié)內(nèi)容,然后介紹文件魔數(shù),最后給出示例基于魔數(shù)判斷文件類型,需要的朋友可以參考下
    2023-02-02
  • go使用SQLX操作MySQL數(shù)據(jù)庫的教程詳解

    go使用SQLX操作MySQL數(shù)據(jù)庫的教程詳解

    sqlx 是 Go 語言中一個流行的操作數(shù)據(jù)庫的第三方包,它提供了對 Go 標(biāo)準(zhǔn)庫 database/sql 的擴(kuò)展,簡化了操作數(shù)據(jù)庫的步驟,下面我們就來學(xué)習(xí)一下go如何使用SQLX實(shí)現(xiàn)MySQL數(shù)據(jù)庫的一些基本操作吧
    2023-11-11
  • go結(jié)構(gòu)體嵌套的切片數(shù)組操作

    go結(jié)構(gòu)體嵌套的切片數(shù)組操作

    這篇文章主要介紹了go結(jié)構(gòu)體嵌套的切片數(shù)組操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Go Java算法之同構(gòu)字符串示例詳解

    Go Java算法之同構(gòu)字符串示例詳解

    這篇文章主要為大家介紹了Go Java算法之同構(gòu)字符串示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • 詳解go語言中并發(fā)安全和鎖問題

    詳解go語言中并發(fā)安全和鎖問題

    這篇文章主要介紹了go語言中并發(fā)安全和鎖問題,包含互斥鎖解鎖過程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-10-10
  • docker如何安裝部署golang應(yīng)用程序

    docker如何安裝部署golang應(yīng)用程序

    這篇文章主要為大家介紹了docker如何安裝部署golang應(yīng)用程序詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • GoLang OS包以及File類型詳細(xì)講解

    GoLang OS包以及File類型詳細(xì)講解

    go中對文件和目錄的操作主要集中在os包中,下面對go中用到的對文件和目錄的操作,做一個總結(jié)筆記。在go中的文件和目錄涉及到兩種類型,一個是type File struct,另一個是type Fileinfo interface
    2023-03-03

最新評論

谢通门县| 晋城| 赤水市| 海淀区| 潍坊市| 扬中市| 丁青县| 公主岭市| 惠州市| 兴和县| 樟树市| 呼玛县| 岚皋县| 齐齐哈尔市| 安平县| 商南县| 深水埗区| 东台市| 万安县| 丘北县| 专栏| 牙克石市| 莱西市| 城口县| 永川市| 琼海市| 忻城县| 江北区| 阿城市| 大荔县| 辽阳市| 金川县| 海南省| 正蓝旗| 西充县| 沛县| 资中县| 大兴区| 青阳县| 新竹县| 广饶县|