go類(lèi)型轉(zhuǎn)換及與C的類(lèi)型轉(zhuǎn)換方式
GO類(lèi)型轉(zhuǎn)換及與C的類(lèi)型轉(zhuǎn)換
類(lèi)型轉(zhuǎn)換
語(yǔ)法
dst := float32(src)
示例
var num int = 520 f32 := float32(num) i64 := int64(num)
注意:加入val是一個(gè)指針,int32(val)相當(dāng)于*(int32(var1)),指針不能直接轉(zhuǎn)換成一個(gè)int32類(lèi)型,應(yīng)該改為(*int32)(var1),所以某些類(lèi)型可能引起誤會(huì)的應(yīng)該用括號(hào)括起來(lái)轉(zhuǎn)換。
類(lèi)型斷言
語(yǔ)法
dst,ok := src.(int) // 安全類(lèi)型斷言,通過(guò)ok判斷是否轉(zhuǎn)換成功 dst := src.(int) // 非安全類(lèi)型斷言,無(wú)法確定是否轉(zhuǎn)換成功
示例
var val interface{} = 123 num,ok := val.(int) if ok { fmt.Printf("%T->%d\n", num, num) } else { fmt.Println("類(lèi)型不匹配") }
其他轉(zhuǎn)換
go提供了strconv包來(lái)進(jìn)行轉(zhuǎn)換
bytes 、string轉(zhuǎn)換
//類(lèi)型轉(zhuǎn)換 string to bytes func str2bytes(s string) []byte { x := (*[2]uintptr)(unsafe.Pointer(&s)) h := [3]uintptr{x[0], x[1], x[1]} return *(*[]byte)(unsafe.Pointer(&h)) } //類(lèi)型轉(zhuǎn)換 bytes to string func bytes2str(b []byte) string { return *(*string)(unsafe.Pointer(&b)) }
interface轉(zhuǎn)為string
//interface轉(zhuǎn)為string func interface2string(inter interface{}) string { tempStr := "" switch inter.(type) { case string: tempStr = inter.(string) break case float64: tempStr = strconv.FormatFloat(inter.(float64), 'f', -1, 64) break case int64: tempStr = strconv.FormatInt(inter.(int64), 10) break case int: tempStr = strconv.Itoa(inter.(int)) break } return tempStr }
//整形轉(zhuǎn)字符串 strconv.Itoa(100) //該方法的源碼是: //可以看出是FormatInt方法的簡(jiǎn)單實(shí)現(xiàn)。 func Itoa(i int) string { return FormatInt(int64(i), 10) } //字符串轉(zhuǎn)整形 i, _ := strconv.Atoi("100") //64位整形轉(zhuǎn)字符串,FormatInt第二個(gè)參數(shù)表示進(jìn)制,10表示十進(jìn)制 var i int64 i = 0x100 strconv.FormatInt(i, 10) //字節(jié)轉(zhuǎn)32位整形 b := []byte{0x00, 0x00, 0x03, 0xe8} bytesBuffer := bytes.NewBuffer(b) //其中binary.BigEndian表示字節(jié)序,相應(yīng)的還有l(wèi)ittle endian。通俗的說(shuō)法叫大端、小端。 var x int32 binary.Read(bytesBuffer, binary.BigEndian, &x) fmt.Println(x) //32位整形轉(zhuǎn)字節(jié) var x int32 x = 106 bytesBuffer := bytes.NewBuffer([]byte{}) binary.Write(bytesBuffer, binary.BigEndian, x) fmt.Println(bytesBuffer.Bytes()) //字節(jié)轉(zhuǎn)字符串 fmt.Println(string([]byte{97, 98, 99, 100})) //字符串轉(zhuǎn)字節(jié) fmt.Println([]byte("abcd"))
string與unicode字符互轉(zhuǎn)
//string-->unicode func Str2uft16ptr(str string)(p uintptr){//將字符串轉(zhuǎn)為utf16指針 e:=utf16.Encode([]rune(str))//轉(zhuǎn)成unicode e=append(e, uint16(0))//添加末尾的0 p=uintptr(unsafe.Pointer(&e[0]))//轉(zhuǎn)成指針 //p=uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(str))) return } //unicode-->string func addbuf(buf []uint16,newcap int)(newbuf []uint16){ newbuf=make([]uint16,newcap) copy(newbuf,buf) return } func Utf16prt2str(p uintptr)(str string){//將utf16指針轉(zhuǎn)為字符串 len:=0 buf:=make([]uint16,64) for a:=(*(*uint16)(unsafe.Pointer(p)));a!=0;len++{ if len>=cap(buf){ buf=addbuf(buf,len*2) } buf[len]=a p+=2//uint16占2字節(jié) a=(*(*uint16)(unsafe.Pointer(p))) } str=string(utf16.Decode(buf[:len])) return }
go和c類(lèi)型裝換
#cgo char --> C.char --> byte signed char --> C.schar --> int8 unsigned char --> C.uchar --> uint8 short int --> C.short --> int16 short unsigned int --> C.ushort --> uint16 int --> C.int --> int unsigned int --> C.uint --> uint32 long int --> C.long --> int32 or int64 long unsigned int --> C.ulong --> uint32 or uint64 long long int --> C.longlong --> int64 long long unsigned int --> C.ulonglong --> uint64 float --> C.float --> float32 double --> C.double --> float64 wchar_t --> C.wchar_t --> void * -> unsafe.Pointer #window uint64 //對(duì)應(yīng)SIZE_T uint32 //對(duì)應(yīng)DWORD
//整型數(shù) //Go->C: var i int ci := C.int(i) //C->Go: var i C.int goi := int(i) //數(shù)組和字符串 //Go->C: var str string cstr := C.CString(str) //C->Go: /* #include <stdlib.h> #include <stdio.h> char foo[] = "hellofoo"; char *bar = "hellobar"; */ import "C" import "fmt" func main() { fmt.Printf("%s\n", C.GoString(&C.foo[0])) fmt.Printf("%s\n", C.GoString(C.bar)) } //數(shù)組類(lèi)型轉(zhuǎn)換 /* #include <stdio.h> int cIArray[] = {1, 2, 3, 4, 5, 6, 7}; //int float cFArray[] = {1.011, 2.022, 3.022, 4.023, 5.02, 6.03, 7.045};//float */ import "C" import "fmt" func main() { goIArray := C.cIArray[:] fmt.Println(goIArray) goFArray := C.cFArray[:] fmt.Println(goFArray) } //[]byte 轉(zhuǎn)換為 *char c_char := (*C.char)(unsafe.Pointer(&bt[0]))
fmt格式字符串:
打印格式 | 含義 |
---|---|
%% | 一個(gè)%字面量 |
%b | 一個(gè)二進(jìn)制整數(shù)值(基數(shù)為2),或者是一個(gè)(高級(jí)的)用科學(xué)計(jì)數(shù)法表示的指數(shù)為2的浮點(diǎn)數(shù) |
%c | 字符型。可以把輸入的數(shù)字按照ASCII碼相應(yīng)轉(zhuǎn)換為對(duì)應(yīng)的字符 |
%d | 一個(gè)十進(jìn)制數(shù)值(基數(shù)為10) |
%e | 以科學(xué)記數(shù)法e表示的浮點(diǎn)數(shù)或者復(fù)數(shù)值 |
%E | 以科學(xué)記數(shù)法E表示的浮點(diǎn)數(shù)或者復(fù)數(shù)值 |
%f | 以標(biāo)準(zhǔn)記數(shù)法表示的浮點(diǎn)數(shù)或者復(fù)數(shù)值 |
%g | 以%e或者%f表示的浮點(diǎn)數(shù)或者復(fù)數(shù),任何一個(gè)都以最為緊湊的方式輸出 |
%G | 以%E或者%f表示的浮點(diǎn)數(shù)或者復(fù)數(shù),任何一個(gè)都以最為緊湊的方式輸出 |
%o | 一個(gè)以八進(jìn)制表示的數(shù)字(基數(shù)為8) |
%p | 以十六進(jìn)制(基數(shù)為16)表示的一個(gè)值的地址,前綴為0x,字母使用小寫(xiě)的a-f表示 |
%q | 使用Go語(yǔ)法以及必須時(shí)使用轉(zhuǎn)義,以雙引號(hào)括起來(lái)的字符串或者字節(jié)切片[]byte,或者是以單引號(hào)括起來(lái)的數(shù)字 |
%s | 字符串。輸出字符串中的字符直至字符串中的空字符(字符串以'\0‘結(jié)尾,這個(gè)'\0'即空字符) |
%t | 以true或者false輸出的布爾值 |
%T | 使用Go語(yǔ)法輸出的值的類(lèi)型 |
%U | 一個(gè)用Unicode表示法表示的整型碼點(diǎn),默認(rèn)值為4個(gè)數(shù)字字符 |
%v | 使用默認(rèn)格式輸出的內(nèi)置或者自定義類(lèi)型的值,或者是使用其類(lèi)型的String()方式輸出的自定義值,如果該方法存在的話 |
%x | 以十六進(jìn)制表示的整型值(基數(shù)為十六),數(shù)字a-f使用小寫(xiě)表示 |
%X | 以十六進(jìn)制表示的整型值(基數(shù)為十六),數(shù)字A-F使用小寫(xiě)表示 |
強(qiáng)制轉(zhuǎn)換 | 隱式轉(zhuǎn)換 | 類(lèi)型斷言 | |
---|---|---|---|
類(lèi)型之間 | 可以 | 不可以 | 可以 |
類(lèi)型->接口 | 可以 | 可以 | 可以 |
接口->類(lèi)型 | 不可以 | 不可以 | 可以 |
接口之間 | 可以(編譯期間確定) | 可以(編譯期間確定) | 可以 |
補(bǔ)充:Golang常見(jiàn)類(lèi)型轉(zhuǎn)換
1.Type(expression):
int(time.Now().Weekday()) //星期轉(zhuǎn)int int(time.Now().Month()) //月份轉(zhuǎn)int
var a float64 a = 3.1 b := int(a) //float64轉(zhuǎn)int
var a int a = 1 b := int64(a) //int轉(zhuǎn)int64
2.strconv包:
string和int、int32、int64:
i, _ := strconv.Atoi(s) //string轉(zhuǎn)int s := strconv.Itoa(i) //int轉(zhuǎn)string
i, _ := strconv.ParseInt(s, 10, 32) //string轉(zhuǎn)int32 ii := int32(I)
i, _ := strconv.ParseInt(s, 10, 64) //string轉(zhuǎn)int32 s := strconv.FormatInt(i, 10) //int64轉(zhuǎn)string
ParseInt函數(shù)的官方介紹:
func ParseInt(s string, base int, bitSize int) (i int64, err error)
–返回字符串表示的整數(shù)值,接受正負(fù)號(hào)。
–base指定進(jìn)制(2到36),如果base為0,則會(huì)從字符串前置判斷,"0x"是16進(jìn)制,"0"是8進(jìn)制,否則是10進(jìn)制。
–bitSize指定結(jié)果必須能無(wú)溢出賦值的整數(shù)類(lèi)型,0、8、16、32、64 分別代表 int、int8、int16、int32、int64。
–返回的err是*NumErr類(lèi)型的,如果語(yǔ)法有誤,err.Error = ErrSyntax;如果結(jié)果超出類(lèi)型范圍err.Error = ErrRange。
FormatInt函數(shù)中的10,表示10進(jìn)制。
string和float32、float64:
f, _ := strconv.ParseFloat(s, 32) //string轉(zhuǎn)float32 ff := float32(f)
f, _ := strconv.ParseFloat(s, 64) //string轉(zhuǎn)float64 s := strconv.FormatFloat(f, 'f', -1, 64) //float64轉(zhuǎn)string
ParseFloat函數(shù)的官方介紹:
func ParseFloat(s string, bitSize int) (f float64, err error)
–解析一個(gè)表示浮點(diǎn)數(shù)的字符串并返回其值。
–如果s合乎語(yǔ)法規(guī)則,函數(shù)會(huì)返回最為接近s表示值的一個(gè)浮點(diǎn)數(shù)(使用IEEE754規(guī)范舍入)。
–bitSize指定了期望的接收類(lèi)型,32是float32(返回值可以不改變精確值的賦值給float32),64是float64。
–返回值err是*NumErr類(lèi)型的,語(yǔ)法有誤的,err.Error=ErrSyntax;結(jié)果超出表示范圍的,返回值f為±Inf,err.Error= ErrRange。
FormatFloat函數(shù)的官方介紹:
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
–bitSize表示f的來(lái)源類(lèi)型(32:float32、64:float64),會(huì)據(jù)此進(jìn)行舍入。
–fmt表示格式:‘f'(-ddd.dddd)、‘b'(-ddddp±ddd,指數(shù)為二進(jìn)制)、‘e'(-d.dddde±dd,十進(jìn)制指數(shù))、‘E'(-d.ddddE±dd,十進(jìn)制指數(shù))、‘g'(指數(shù)很大時(shí)用'e'格式,否則'f'格式)、‘G'(指數(shù)很大時(shí)用'E'格式,否則'f'格式)。
–prec控制精度(排除指數(shù)部分):對(duì)'f'、‘e'、‘E',它表示小數(shù)點(diǎn)后的數(shù)字個(gè)數(shù);對(duì)'g'、‘G',它控制總的數(shù)字個(gè)數(shù)。如果prec 為-1,則代表使用最少數(shù)量的、但又必需的數(shù)字來(lái)表示f。
string和time:
t, _ := time.Parse("2006-01-02 15:04:05", s) //string轉(zhuǎn)時(shí)間 t, _ := time.ParseInLocation("2006-01-02 15:04:05", s, time.Local) //string轉(zhuǎn)本地時(shí)間 s := t.Format("2006-01-02 15:04:05") //時(shí)間轉(zhuǎn)string
3.類(lèi)型斷言:expression.(Type):
expression必須是接口類(lèi)型,且自身類(lèi)型與Type類(lèi)型相符。
expression.(Type)的返回值一般為兩個(gè):value和ok,匹配成功ok為true,value有值,匹配失敗ok為false,value無(wú)值;也可以直接接受value一個(gè)返回值,不過(guò)失敗則直接panic:
func main() { var a interface{} = 100 if aa, ok := a.(int); ok { fmt.Println(aa) } }
還可以結(jié)合switch和case使用,來(lái)判斷接口實(shí)際類(lèi)型:
func main() { var t interface{} = 100 switch i := t.(type) { case float32: fmt.Printf("i的類(lèi)型%T i的值%v\n", i, i) case float64: fmt.Printf("i的類(lèi)型%T i的值%v\n", i, i) case int: fmt.Printf("i的類(lèi)型%T i的值%v\n", i, i) case bool: fmt.Printf("i的類(lèi)型%T i的值%v\n", i, i) case string: fmt.Printf("i的類(lèi)型%T i的值%v\n", i, i) default: fmt.Println("其他類(lèi)型") } }
4.JSON:
Golang中大多數(shù)數(shù)據(jù)類(lèi)型都可以轉(zhuǎn)化為有效的JSON文本,除了channel通道、complex復(fù)數(shù)、func函數(shù)等。
Golang指針可進(jìn)行隱式轉(zhuǎn)換,表面進(jìn)行的是指針序列化,內(nèi)部會(huì)針對(duì)指針進(jìn)行取值操作,實(shí)際還是針對(duì)所指的對(duì)象進(jìn)行序列化。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
Go語(yǔ)言利用time.After實(shí)現(xiàn)超時(shí)控制的方法詳解
最近在學(xué)習(xí)golang,所以下面這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言利用time.After實(shí)現(xiàn)超時(shí)控制的相關(guān)資料,文中通過(guò)示例介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08Golang設(shè)計(jì)模式之適配器模式詳細(xì)講解
這篇文章主要介紹了使用go實(shí)現(xiàn)適配器模式,這個(gè)模式就是用來(lái)做適配的,它將不兼容的接口轉(zhuǎn)換為可兼容的接口,讓原本由于接口不兼容而不能一起工作的類(lèi)可以一起工作,需要的朋友可以參考下2023-01-01go語(yǔ)言的工作空間和GOPATH環(huán)境變量介紹
這篇文章主要介紹了go語(yǔ)言的工作空間和GOPATH環(huán)境變量介紹,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12golang基礎(chǔ)之字符串與int、int64類(lèi)型互相轉(zhuǎn)換
這篇文章主要給大家介紹了關(guān)于golang基礎(chǔ)之字符串與int、int64類(lèi)型互相轉(zhuǎn)換的相關(guān)資料,在Go語(yǔ)言中string轉(zhuǎn)int是一項(xiàng)常見(jiàn)的操作,需要的朋友可以參考下2023-07-07一百行Golang代碼實(shí)現(xiàn)簡(jiǎn)單并發(fā)聊天室
這篇文章主要為大家詳細(xì)介紹了一百行Golang代碼如何實(shí)現(xiàn)簡(jiǎn)單并發(fā)聊天室,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08GoLang之標(biāo)準(zhǔn)庫(kù)encoding/json包
本文主要介紹了GoLang之標(biāo)準(zhǔn)庫(kù)encoding/json包,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08一篇文章帶你搞懂Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)Time
在我們開(kāi)發(fā)的過(guò)程中,每個(gè)項(xiàng)目都需要時(shí)間這一類(lèi)的函數(shù),此時(shí)對(duì)time這個(gè)包的研究深度就顯得尤為重要,這篇文章主要給大家介紹了關(guān)于如何通過(guò)一篇文章帶你搞懂Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)Time的相關(guān)資料,需要的朋友可以參考下2022-10-10