由于golang是一門強類型的語言, 所以我們在golang的開發中不可避免的會對一些數據類型進行手動轉換,以適應我們的業務需求。?
golang中類型轉換的途徑大致有4種,強制轉換,類型斷言,類型匹配 還有使用strconv包中提供的轉換函數, 下面我們分別舉例說明。
1. 強制轉換? ?類型(變量名)
強制類型轉換一般用于對已知類型(非any類型)進行高低精度之間的轉換,如從 int 轉換為 int64, 或者 int轉換為 uint ,? float32轉換為 float64 這類的轉換, 這類型的轉換較為簡單,
- 轉換語法: 類型(變量名)? ?
- 語法說明:這里的類型即是你要轉換到的類型,變量名是你要轉換的變量名稱
- 強制轉換示例:
var? x1 int = 10 // 聲明一個int類型變量 x1 并賦值為 10x2 := uint64(x1) // 將x1強制轉換為uint64類型并賦值給x2
- 細節說明:
- ?從高精度到低精度轉換會有丟失精度的風險;
- 對于any類型(即空接口類型interface{})的數據不能使用強制轉換。
2. 類型斷言? ?i變量名.(類型)
類型斷言一個專門用于any類型(也就是 interface{}空接口類型,他們是一個東西)的數據類型轉換的。?
語法:??i變量名.(類型)?
說明: 這里的 i變量名 指的就是你自己定義的interface{} 類型的變量名,注意必須是空接口類型,其他類型的變量名不能應用類型斷言!!
這里的 類型? ?則可以是任意的類型,包括內置類型,和你自己定義的結構體或者接口都可以繼續斷言。 當然 any 也可以作為這里的類型進行斷言的
類型斷言示例:
func ExampleTypeAsserts() {var ival1 interface{} = 1// 對變量 ival1 進行 int數據類型斷言, 斷言后可返回2個值, 第二個值表示是否斷言成功, 第一個是斷言成功后的斷言類型的值if int1, ok := ival1.(int); ok {fmt.Printf("%v 的類型是: %T \n", int1, int1) // output: 1 的類型是: int}// 如果你確定這個類型就是某個類型,斷言也可以只用一個變量接收, 這種情況下,如果斷言失敗,則會拋panic異常,所以這種方式要慎用!// int2 := ival1.(int64) // 這個就會拋異常 panic: interface conversion: interface {} is int, not int64int2 := ival1.(int) // okfmt.Printf("%v 的類型是: %T \n", int2, int2) // output: 1 的類型是: int// any 類型是interface{} 的一個別名 他們是一個東西var tsx anytsx = time.Now()// 對象斷言if ts,ok:=tsx.(time.Time);ok {// 這里ts就是斷言成功后的time類型的對象, 我們就可以調用他的方法 ts.Format(time.RFC3339)// 但是tsx 里面是不能直接調用time方法的, 雖然你知道你賦值了一個時間對象給他,這點一定要注意!!fmt.Printf("ts的類型為 %T , 值為: %v", ts, ts.Format(time.RFC3339)) // output: a}}
3. 類型匹配? i變量名.(type)
這個也是專門用于處理any類型的數據的, 需要注意的是?i變量名.(type) 只能用在 switch語句上面。 他用于對any類型的數據進行類型匹配和處理。 如我們需要對不同類型的變量進行不同的處理時就用它。
語法:? switch??i變量名.(type) {? case xxx:? ?}
說明: i變量名 這個和上面的一樣;?.(type) ?這時固定的用法,用于獲取i變量名對應的類型; 后面的case語句就是 定義不同類型時的處理邏輯的,case 后面的 xxx 這個是你要判斷的 類型,這里可以是任意的類型,包括內置類型或者你自己定義的類型或者接口
示例:
func ExampleTypeType() {var inter1 interface{}inter1 = 88.8 // 我們給這個變量 賦值一個float64類型的數, go里面對于否點數默認為 float64類型switch inter1.(type) {case int:fmt.Printf("inter1: %v 是int類型的數據", inter1) // 這個不會被執行case float64:fmt.Printf("inter1: %v 是float64類型的數據", inter1) // output: inter1: 88.8 是float64類型的數據case time.Time:fmt.Printf("inter1: %v 是time.Time類型的數據", inter1) // 這個也不會被執行}}
4.strconv提供的轉換函數
這個官方提供的包里面包含了非常多的轉換函數,其中較為常用的是ParseXXX, FormatXXX 和 Atoi, 和 Itoa, 他們的使用相對比較簡單,看看函數定義就可以使用。
strconv.Atoi("123") // 將字符串轉換為int
strconv.Itoa(456) //將int轉換為字符串
下面是strconv中所定義的函數一覽表
func AppendBool(dst []byte, b bool) []byte
func AppendFloat(dst []byte, f float64, fmt byte, prec, bitSize int) []byte
func AppendInt(dst []byte, i int64, base int) []byte
func AppendQuote(dst []byte, s string) []byte
func AppendQuoteRune(dst []byte, r rune) []byte
func AppendQuoteRuneToASCII(dst []byte, r rune) []byte
func AppendQuoteRuneToGraphic(dst []byte, r rune) []byte
func AppendQuoteToASCII(dst []byte, s string) []byte
func AppendQuoteToGraphic(dst []byte, s string) []byte
func AppendUint(dst []byte, i uint64, base int) []byte
func Atoi(s string) (int, error)
func CanBackquote(s string) bool
func FormatBool(b bool) string
func FormatComplex(c complex128, fmt byte, prec, bitSize int) string
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
func FormatInt(i int64, base int) string
func FormatUint(i uint64, base int) string
func IsGraphic(r rune) bool
func IsPrint(r rune) bool
func Itoa(i int) string
func ParseBool(str string) (bool, error)
func ParseComplex(s string, bitSize int) (complex128, error)
func ParseFloat(s string, bitSize int) (float64, error)
func ParseInt(s string, base int, bitSize int) (i int64, err error)
func ParseUint(s string, base int, bitSize int) (uint64, error)
func Quote(s string) string
func QuoteRune(r rune) string
func QuoteRuneToASCII(r rune) string
func QuoteRuneToGraphic(r rune) string
func QuoteToASCII(s string) string
func QuoteToGraphic(s string) string
func QuotedPrefix(s string) (string, error)
func Unquote(s string) (string, error)
func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error)
type NumError
func (e *NumError) Error() string
func (e *NumError) Unwrap() error