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

Golang泛型實(shí)現(xiàn)類型轉(zhuǎn)換的方法實(shí)例

 更新時(shí)間:2022年12月30日 11:45:25   作者:戀喵大鯉魚  
將一個(gè)值從一種類型轉(zhuǎn)換到另一種類型,便發(fā)生了類型轉(zhuǎn)換,下面這篇文章主要給大家介紹了關(guān)于Golang泛型實(shí)現(xiàn)類型轉(zhuǎn)換的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

1.前言

Golang 標(biāo)準(zhǔn)庫提供了很多類型轉(zhuǎn)換的函數(shù),如 strconv 包可完成 string 與基本數(shù)據(jù)類型之間的轉(zhuǎn)換。

比如將 int 與 string 之間的互轉(zhuǎn)。

// int to string
s := strconv.Itoa(i)

// string to int
i, err := strconv.ParseInt(i, 0, 64)

如果我們想完成任意類型到某一具體類型的轉(zhuǎn)換,該如何實(shí)現(xiàn)呢?

2.To String

以 string 為,我們可以這樣實(shí)現(xiàn)。

// ToStringE casts any type to a string type.
func ToStringE(i any) (string, error) {
	i = indirectToStringerOrError(i)

	switch s := i.(type) {
	case string:
		return s, nil
	case bool:
		return strconv.FormatBool(s), nil
	case float64:
		return strconv.FormatFloat(s, 'f', -1, 64), nil
	case float32:
		return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
	case int:
		return strconv.Itoa(s), nil
	case int64:
		return strconv.FormatInt(s, 10), nil
	case int32:
		return strconv.Itoa(int(s)), nil
	case int16:
		return strconv.FormatInt(int64(s), 10), nil
	case int8:
		return strconv.FormatInt(int64(s), 10), nil
	case uint:
		return strconv.FormatUint(uint64(s), 10), nil
	case uint64:
		return strconv.FormatUint(uint64(s), 10), nil
	case uint32:
		return strconv.FormatUint(uint64(s), 10), nil
	case uint16:
		return strconv.FormatUint(uint64(s), 10), nil
	case uint8:
		return strconv.FormatUint(uint64(s), 10), nil
	case json.Number:
		return s.String(), nil
	case []byte:
		return string(s), nil
	case template.HTML:
		return string(s), nil
	case template.URL:
		return string(s), nil
	case template.JS:
		return string(s), nil
	case template.CSS:
		return string(s), nil
	case template.HTMLAttr:
		return string(s), nil
	case nil:
		return "", nil
	case fmt.Stringer:
		return s.String(), nil
	case error:
		return s.Error(), nil
	default:
		return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i)
	}
}

其中 indirectToStringerOrError 是對(duì)指針類型的解引用,從標(biāo)準(zhǔn)庫 html/template/content.go 獲取。

var (
	errorType       = reflect.TypeOf((*error)(nil)).Elem()
	fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
)

// Copied from html/template/content.go.
// indirectToStringerOrError returns the value, after dereferencing as many times
// as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
// or error,
func indirectToStringerOrError(a any) any {
	if a == nil {
		return nil
	}
	v := reflect.ValueOf(a)
	for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Pointer && !v.IsNil() {
		v = v.Elem()
	}
	return v.Interface()
}

3.To Other Type

那么對(duì)其他類型我們也都要實(shí)現(xiàn)對(duì)應(yīng)的轉(zhuǎn)換函數(shù)。

// ToBoolE casts any type to a bool type.
func ToBoolE(i any) (bool, error) {
	i = indirect(i)

	switch b := i.(type) {
	case bool:
		return b, nil
	case nil:
		return false, nil
	case int:
		if i.(int) != 0 {
			return true, nil
		}
		return false, nil
	case string:
		return strconv.ParseBool(i.(string))
	default:
		return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
	}
}

// ToIntE, ToInt8E, ToInt16E...

3.泛型

最終,我們可以通過泛型完成對(duì)上面多個(gè)具體類型轉(zhuǎn)換函數(shù)的封裝。這樣我們只需要調(diào)用一個(gè)函數(shù),便可完成對(duì)所有類型的轉(zhuǎn)換。

// ToAnyE converts one type to another and returns an error if occurred.
func ToAnyE[T any](a any) (T, error) {
	var t T
	switch any(t).(type) {
	case bool:
		v, err := ToBoolE(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case int:
		v, err := ToIntE(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case int8:
		v, err := ToInt8E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case int16:
		v, err := ToInt16E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case int32:
		v, err := ToInt32E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case int64:
		v, err := ToInt64E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case uint:
		v, err := ToUintE(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case uint8:
		v, err := ToUint8E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case uint16:
		v, err := ToUint16E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case uint32:
		v, err := ToUint32E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case uint64:
		v, err := ToUint64E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case float32:
		v, err := ToFloat32E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case float64:
		v, err := ToFloat64E(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	case string:
		v, err := ToStringE(a)
		if err != nil {
			return t, err
		}
		t = any(v).(T)
	default:
		return t, fmt.Errorf("the type %T is not supported", t)
	}
	return t, nil
}

如果不關(guān)心錯(cuò)誤,可以再封裝一下。

// ToAny converts one type to another type.
func ToAny[T any](a any) T {
	v, _ := ToAnyE[T](a)
	return v
}

4.使用示例

package main

import (
	"fmt"
)

func main() {
	fmt.Println(ToAny[string](1))    // "1"
	fmt.Println(ToAny[string](true)) // "true"
	fmt.Println(ToAny[string](1.1))  // "1.1"

	fmt.Println(ToAny[int]("1"))   	// 1
	fmt.Println(ToAny[int]("1.0")) 	// 1
	fmt.Println(ToAny[int](true))  	// 1

	fmt.Println(ToAny[bool]("true"))  // true
	fmt.Println(ToAny[bool]("false")) // false
	fmt.Println(ToAny[bool]("True"))  // true
	fmt.Println(ToAny[bool]("False")) // false
	fmt.Println(ToAny[bool](1))       // true
	fmt.Println(ToAny[bool](0))       // false
	fmt.Println(ToAny[bool](nil))     // false
}

5.go-huge-util

為了方便大家使用,以上相關(guān)代碼已開源至 Github 工具庫 go-huge-util,大家可使用 go mod 方式 import 然后使用。

import "github.com/dablelv/go-huge-util/conv"

conv.ToAny[string](1)    // "1"
conv.ToAny[string](true) // "true"
conv.ToAny[string](1.1)  // "1.1"

conv.ToAny[int]("1")   // 1
conv.ToAny[int]("1.0") // 1
conv.ToAny[int](true)  // 1

conv.ToAny[bool]("true")  // true
conv.ToAny[bool]("false") // false
conv.ToAny[bool]("True")  // true
conv.ToAny[bool]("False") // false
conv.ToAny[bool](1)       // true
conv.ToAny[bool](0)       // false
conv.ToAny[bool](nil)     // false

go-huge-util 除了類型轉(zhuǎn)換,還有很多其他實(shí)用函數(shù),如加解密、zip 等,歡迎大家使用、Star 和 Pull Request。

參考文獻(xiàn)

github.com/dablelv/go-huge-util

總結(jié)

到此這篇關(guān)于Golang泛型實(shí)現(xiàn)類型轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)Golang泛型類型轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang如何使用gomobile進(jìn)行Android開發(fā)

    golang如何使用gomobile進(jìn)行Android開發(fā)

    golang可以開發(fā)android,使用golang開發(fā)android需要下載安裝gomobile,下面這篇文章主要給大家介紹了關(guān)于golang如何使用gomobile進(jìn)行Android開發(fā)的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • 優(yōu)雅使用GoFrame共享變量Context示例詳解

    優(yōu)雅使用GoFrame共享變量Context示例詳解

    這篇文章主要為大家介紹了優(yōu)雅使用GoFrame共享變量Context示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 超全講解Golang中defer關(guān)鍵字的用法

    超全講解Golang中defer關(guān)鍵字的用法

    本文將從一個(gè)資源回收問題引入,引出defer關(guān)鍵字,并對(duì)其進(jìn)行基本介紹,從而讓大家對(duì)Go語言中的defer有更深入的了解,需要的小伙伴可以學(xué)習(xí)一下
    2023-05-05
  • 源碼解析gtoken替換jwt實(shí)現(xiàn)sso登錄

    源碼解析gtoken替換jwt實(shí)現(xiàn)sso登錄

    這篇文章主要為大家介紹了源碼解析gtoken替換jwt實(shí)現(xiàn)sso登錄的示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • golang gorm 操作mysql及gorm基本用法

    golang gorm 操作mysql及gorm基本用法

    golang 官方的那個(gè)操作mysql的有點(diǎn)麻煩所以就使用了gorm,下面就gorm的使用做下簡(jiǎn)單介紹,感興趣的朋友跟隨小編一起看看吧
    2018-11-11
  • Go語言上下文context底層原理

    Go語言上下文context底層原理

    這篇文章主要介紹了Go語言上下文context底層原理,context是Go中用來進(jìn)程通信的一種方式,其底層是借助channl與snyc.Mutex實(shí)現(xiàn)的,更多相關(guān)內(nèi)容需要的小伙伴可以參加一下
    2022-06-06
  • 如何使用騰訊云go sdk 查詢對(duì)象存儲(chǔ)中最新文件

    如何使用騰訊云go sdk 查詢對(duì)象存儲(chǔ)中最新文件

    這篇文章主要介紹了使用騰訊云go sdk 查詢對(duì)象存儲(chǔ)中最新文件,這包括如何創(chuàng)建COS客戶端,如何逐頁檢索對(duì)象列表,并如何對(duì)結(jié)果排序以找到最后更新的對(duì)象,我們還展示了如何優(yōu)化用戶體驗(yàn),通過實(shí)時(shí)進(jìn)度更新和檢索多個(gè)文件來改進(jìn)程序,需要的朋友可以參考下
    2024-03-03
  • Golang實(shí)現(xiàn)常見的限流算法的示例代碼

    Golang實(shí)現(xiàn)常見的限流算法的示例代碼

    限流是項(xiàng)目中經(jīng)常需要使用到的一種工具,一般用于限制用戶的請(qǐng)求的頻率,也可以避免瞬間流量過大導(dǎo)致系統(tǒng)崩潰,或者穩(wěn)定消息處理速率,本文主要介紹了使用Go實(shí)現(xiàn)常見的限流算法,希望對(duì)大家有所幫助
    2023-04-04
  • go module使用本地包的方法示例

    go module使用本地包的方法示例

    這篇文章主要介紹了go module使用本地包的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-03-03
  • go開源Hugo站點(diǎn)渲染之模板詞法解析

    go開源Hugo站點(diǎn)渲染之模板詞法解析

    這篇文章主要為大家介紹了go開源Hugo站點(diǎn)渲染之模板詞法解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02

最新評(píng)論

盱眙县| 婺源县| 达拉特旗| 报价| 阿尔山市| 镇沅| 塔城市| 平遥县| 大厂| 濮阳市| 呼玛县| 河池市| 和龙市| 岑溪市| 银川市| 莆田市| 滨海县| 东辽县| 南康市| 遂平县| 永昌县| 青河县| 同江市| 漾濞| 浮山县| 乌苏市| 陕西省| 大连市| 斗六市| 长白| 开江县| 云梦县| 建宁县| 丁青县| 汶上县| 哈尔滨市| 道真| 那曲县| 陵水| 泰和县| 道孚县|