天天看點

3、Go基礎資料類型一、Go資料類型二、字元串三、強制類型轉換

目錄

  • 一、Go資料類型
  • 二、字元串
  • 三、強制類型轉換

一、Go資料類型

  • 基礎資料類型
類型 長度(位元組) 預設值 說明
bool 1 false
byte 1 uint8,取值範圍[0,255]
rune 4 Unicode Code Point, int32
int, uint 4或8 32 或 64 位,取決于作業系統
int8, uint8 1 -128 ~ 127, 0 ~ 255
int16, uint16 2 -32768 ~ 32767, 0 ~ 65535
int32, uint32 4 -21億~ 21億, 0 ~ 42億,rune是int32 的别名
int64, uint64 8
float32 4 0.0
float64 8 0.0
complex64 8
complex128 16
uintptr 4或8 以存儲指針的 uint32 或 uint64 整數
func main() {
	var m complex64
	m = complex(2, 6)
	fmt.Printf("%T %T\n", real(m), imag(m))           // float32 float32 實部32,虛部32,加起來就是64
	fmt.Printf("real=%f  img=%f\n", real(m), imag(m)) //real=2.000000  img=6.000000

	var n complex128
	n = complex(2, 6)
	fmt.Printf("%T %T\n", real(n), imag(n))           //float64 float64 實部64,虛部64,加起來就是128
	fmt.Printf("real=%f  img=%f\n", real(n), imag(n)) //real=2.000000  img=6.000000

}
           
  • 三種指針類型都是同一個位址
func main() {
	var a int
	// unsafe.Pointer 是特别定義的一種指針類型,它可以包含任意類型變量的位址(類似 C 語言中的 void 類型指針)
	var pointer unsafe.Pointer = unsafe.Pointer(&a)
	var p uintptr = uintptr(pointer)
	var ptr *int = &a
	fmt.Printf("pointer=%p  ,  p=%d  %x,  ptr=%p\n", pointer, p, p, ptr)
	//pointer=0xc0000a6058  ,  p=824634400856  c0000a6058,  ptr=0xc0000a6058

}
           
  • 複合資料類型:
    • 數值型變量的預設值是0,字元串的預設值是空字元串,布爾型變量的預設值是false
    • 引用類型、函數、指針、接口的預設值是nil
    • 數組的預設值取每個元素對應類型的預設值
    • 結構體的預設值取每個成員變量對應類型的預設值
類型 預設值 說明
array 取每個元素對應類型的預設值 值類型
struct 取每個成員變量對應類型的預設值 值類型
string “” UTF-8 字元串
slice nil 引用類型
map nil 引用類型
channel nil 引用類型
interface nil 接口
function nil 函數
func defaultValue() {
	var a int
	var b byte
	var f float32
	var t bool
	var s string
	var r rune
	var arr [3]int
	var slc []int

	fmt.Printf("default value of int %d\n", a)           //default value of int 0
	fmt.Printf("default value of byte %d\n", b)          //default value of byte 0
	fmt.Printf("default value of float32 %.2f\n", f)     //default value of float32 0.00
	fmt.Printf("default value of bool %t\n", t)          //default value of bool false
	fmt.Printf("default value of string [%s]\n", s)      //default value of string []
	fmt.Printf("default value of rune %d, [%c]\n", r, r) //default value of rune 0, []
	fmt.Printf("default int array is %v\n", arr)         //取每個元素對應類型的預設值 default int array is [0 0 0]
	fmt.Printf("default slice is nil %t\n", slc == nil)  //default slice is nil true
}
           
  • 自定義類型
    • 類型别名
      • type byte = uint8

      • type rune = int32

    • 自定義類型
      • type user struct {name string;age int}

      • type signal uint8

      • type ms map[string]string

      • type add func(a, b int) int

type ms map[string]int

func (s ms) Say() {
	fmt.Printf("%d\n", s["hello"])
}
           

二、字元串

  • 字元串定義
package main

import "fmt"

func main() {
	s1 := " My name is 張朝陽☻"                       //字元串裡可以包含任意Unicode字元
	s2 := "He say:\"I'm fine.\" \n\\Thank\tyou.\\" //字元串裡可以包含任意Unicode字元

	//字元串也可以用反引号來定義,反引号裡的轉義字元無效。反引号裡的内容原封不動地輸出,包括空白符和換行符

	s3 := `here is first line. 

  there is third line.
`

	fmt.Printf("%s\n", s1)
	fmt.Printf("%s\n", s2)
	fmt.Printf("%s\n", s3)
}

           
3、Go基礎資料類型一、Go資料類型二、字元串三、強制類型轉換
  • 字元串常用操作
方法 介紹
len(str) 求長度
strings.Split 分割
strings.Contains 判斷是否包含
strings.HasPrefix,strings.HasSuffix 字首/字尾判斷
strings.Index(),strings.LastIndex() 子串出現的位置
func main() {
	s := "張"
	arr := []byte(s)
	for _, ele := range arr { //一個漢字占用3個byte表示
		fmt.Printf("%d ", ele) // 229 188 160
	}
	fmt.Println()
	fmt.Printf("%d %d\n", len(s), len(arr)) //3 3

	brr := []rune(s)
	for _, ele := range brr { //一個rune就可以表示一個漢字
		fmt.Printf("%d ", ele) // 24352
	}
	fmt.Println()
	fmt.Printf("%d %d", len(s), len(brr)) //3 1
}

//
func main() {
	s := "張2"
	arr := []byte(s)
	brr := []rune(s)
	fmt.Printf("%d %c\n", s[1], s[1])     //188 ¼
	fmt.Printf("%d %c\n", arr[1], arr[1]) //188 ¼
	fmt.Printf("%d %c\n", brr[1], brr[1]) //50 2(字元2,在Unicode編碼中為50)

}
//
func main() {
	s := "hello, how are u"
	arr := strings.Split(s, ",")
	for _, ele := range arr {
		fmt.Println(ele)
		//hello
		// how are u
	}

	fmt.Printf("%t\n", strings.Contains(s, "how")) //true
	fmt.Printf("%t\n", strings.HasPrefix(s, "he")) //true
	fmt.Printf("%t\n", strings.HasPrefix(s, "hE")) //false
	fmt.Printf("%t\n", strings.HasSuffix(s, " u")) //true
	fmt.Printf("%t\n", strings.HasSuffix(s, "a"))  //false

	pos := strings.Index(s, "lo")
	fmt.Printf("%d\n", pos)                       //3
	fmt.Printf("%d\n", strings.Index(s, "e"))     //1(首次出現e的位置)
	fmt.Printf("%d\n", strings.LastIndex(s, "e")) //13(最後出現e的位置)

	fmt.Printf("%d\n", strings.IndexAny(s, "oe")) //1(查找任意一個字元的位置)
}
           
  • 字元串拼接
    • 加号連接配接
    • func fmt.Sprintf(format string, a …interface{}) string
    • func strings.Join(elems []string, sep string) string
    • 當有大量的string需要拼接時,用strings.Builder效率最高
  • byte和rune
    • string中每個元素叫“字元”,字元有兩種
      • byte:1個位元組, 代表ASCII碼的一個字元
      • rune:4個位元組,代表一個UTF-8字元,一個漢字可用一個rune表示
    • string是常量,不能修改其中的字元
    • string可以轉換為[]byte或[]rune類型
    • string的底層是byte數組,string的長度就是該byte數組的長度,UTF-8編碼下一個漢字占3個byte,即一個漢字占3個長度
func main() {
	s1 := "aaa"
	s2 := "bbb"
	s3 := "ccc"

	S1 := s1 + " " + s2 + " " + s3
	S2 := fmt.Sprintf("%s %s %s", s1, s2, s3)
	S3 := strings.Join([]string{s1, s2, s3}, " ") //性能較高

	sb := strings.Builder{} //性能最高
	sb.WriteString(s1)
	sb.WriteString(" ")
	sb.WriteString(s2)
	sb.WriteString(" ")
	sb.WriteString(s3)
	S4 := sb.String()

	fmt.Println(S1) //aaa bbb ccc
	fmt.Println(S2) //aaa bbb ccc
	fmt.Println(S3) //aaa bbb ccc
	fmt.Println(S4) //aaa bbb ccc

}
           

三、強制類型轉換

  • 強制類型轉換:基本方法就是把目标類型放在變量前面,把變量括起來
    • 低精度向高精度轉換沒問題,高精度向低精度轉換會丢失位數
    • 無符号向有符号轉換,最高位是符号位
    • 不同長度的int或float之間可以互相轉換
    • byte和int可以互相轉換;float和int可以互相轉換,小數位會丢失;bool和int不能互相轉換
func main() {
	var i int = 9
	var by byte = byte(i) //int轉為byte
	i = int(by)           //byte轉為int
	
	//高精度向低精度轉換,數字很小時這種轉換沒問題
	var ua uint64 = 1
	i8 := int8(ua)
	fmt.Printf("i8=%d\n", i8) //i8=1

	//最高位的1變成了符号位
	ua = uint64(math.MaxUint64)
	i64 := int64(ua)
	fmt.Printf("i64=%d\n", i64) //i64=-1

	//位數丢失
	ui32 := uint32(ua)
	fmt.Printf("ui32=%d\n", ui32) //ui32=4294967295

	//單個字元可以轉為int
	var i int = int('a')
	fmt.Printf("i=%d\n", i) //97

	//bool和int不能互相轉換

	//byte和int可以互相轉換
	var by byte = byte(i)
	i = int(by)
	fmt.Printf("i=%d\n", i) //97

	//float和int可以互相轉換,小數位會丢失
	var ft float32 = float32(i)
	i = int(ft)
	fmt.Printf("i=%d\n", i) //97
}
           

繼續閱讀