package main

import (
   "fmt"
   "math"
   "unsafe"
)

func main() {

   // 1.数据类型-整形 有符号型 一般情况下使用int作为整形宽度 在系统是32位情况下就是32 64位系统下就是64
   var num int = math.MaxInt
   var num8 int8 = math.MaxInt8
   var num16 int16 = math.MaxInt16
   var num32 int32 = math.MaxInt32
   var num64 int64 = math.MaxInt64

   fmt.Printf("num=%d,num的大小是:%d,num的类型是:%T\n", num, unsafe.Sizeof(num), num)
   // num=9223372036854775807,num的大小是:8,num的类型是:int

   fmt.Printf("num8=%d,num8的大小是:%d,num8的类型是:%T\n", num8, unsafe.Sizeof(num8), num8)
   // num8=127,num8的大小是:1,num8的类型是:int8

   fmt.Printf("num16=%d,num16的大小是:%d,num16的类型是:%T\n", num16, unsafe.Sizeof(num16), num16)
   // num16=32767,num16的大小是:2,num16的类型是:int16

   fmt.Printf("num32=%d,num32的大小是:%d,num32的类型是:%T\n", num32, unsafe.Sizeof(num32), num32)
   // num32=2147483647,num32的大小是:4,num32的类型是:int32

   fmt.Printf("num64=%d,num64的大小是:%d,num64的类型是:%T\n", num64, unsafe.Sizeof(num64), num64)
   //num64=9223372036854775807,num64的大小是:8,num64的类型是:int64

   // 2.无符号类型
   var numOne uint = math.MaxUint
   var numOne8 uint8 = math.MaxUint8
   var numOne16 uint16 = math.MaxUint16
   var numOne32 uint32 = math.MaxUint32
   var numOne64 uint64 = math.MaxUint64

   fmt.Printf("numOne=%d,numOne的大小是:%d,numOne的类型是:%T\n",
      numOne, unsafe.Sizeof(numOne), numOne)
   // numOne=18446744073709551615,numOne的大小是:8,numOne的类型是:uint

   fmt.Printf("numOne8=%d,numOne8的大小是:%d,numOne8的类型是:%T\n",
      numOne8, unsafe.Sizeof(numOne8), numOne8)
   // numOne8=255,numOne8的大小是:1,numOne8的类型是:uint8

   fmt.Printf("numOne16=%d,numOne16的大小是:%d,numOne16的类型是:%T\n",
      numOne16, unsafe.Sizeof(numOne16), numOne16)
   // numOne16=65535,numOne16的大小是:2,numOne16的类型是:uint16

   fmt.Printf("numOne32=%d,numOne32的大小是:%d,numOne32的类型是:%T\n",
      numOne32, unsafe.Sizeof(numOne32), numOne32)
   // numOne32=4294967295,numOne32的大小是:4,numOne32的类型是:uint32

   fmt.Printf("numOne64=%d,numOne64的大小是:%d,numOne64的类型是:%T\n",
      numOne64, unsafe.Sizeof(numOne64), numOne64)
   // numOne64=18446744073709551615,numOne64的大小是:8,numOne64的类型是:uint64

   // 浮点类型 float32 精度小数点后五个十进制数 float64精度小数点后十五个十进制数
   var numTwo32 float32 = math.MaxFloat32
   var numTwo64 float64 = math.MaxFloat64

   fmt.Printf("numTwo32=%g,numTwo32的大小是:%d,numTwo32的类型是%T\n",
      numTwo32, unsafe.Sizeof(numTwo32), numTwo32)
   // numTwo32=3.4028235e+38,numTwo32的大小是:4,numTwo32的类型是float32

   fmt.Printf("numTwo64=%g,numTwo64的大小是:%d,numTwo64的类型是%T\n",
      numTwo64, unsafe.Sizeof(numTwo64), numTwo64)
   // numTwo64=1.7976931348623157e+308,numTwo64的大小是:8,numTwo64的类型是float64

   // 3.字符 对应字符的阿斯克码
   var byteOne byte = 65
   var uintOne8 uint8 = 65

   fmt.Printf("byteOne = %c\n", byteOne)   // byteOne = A
   fmt.Printf("uintOne8 = %c\n", uintOne8) // uintOne8 = A

   var byteTwo rune = 'S'
   fmt.Printf("byteTwo = %c,byteTwo的大小是:%d\n", byteTwo, unsafe.Sizeof(byteTwo))
   // byteTwo = S,byteTwo的大小是:4

   // 4.字符串 双引号书写字符串被称为字符串字面量(string literal)这种字面量不能跨行。
   var name string = "sunny"                                      // name := "sunny"
   fmt.Printf("name = %s,name的大小是:%d", name, unsafe.Sizeof(name)) // name = sunny,name的大小是:16

   // 多行字符串需要使用反引号“`”,多用于内嵌源码和内嵌数据。在反引号中的所有代码不会被编译器识别,而只是作为字符串的一部分。
   var str1 string
   str1 = `
          name := sunny
          weChat := 1987286894
         `
   fmt.Println(str1) // name := sunny weChat := 1987286894

   // 5.布尔类型 true、false表示,Go中true不与1相等,false不与0相等
   boolOne := true
   booTwo := false

   fmt.Println("boolOne=", boolOne) // boolOne= true
   fmt.Println("booTwo=", booTwo)   // boolOne= false

   // && 一个为false 表达式返回false
   fmt.Println("boolOne && booTwo = ", boolOne && booTwo) // boolOne && booTwo =  false

   // || 一个为true 表达式返回true
   fmt.Println("boolOne || booTwo = ", boolOne || booTwo) // boolOne && booTwo =  false

   // 6.复数型 复数型用于表示数学中的复数 如 1+2i 1-2i -1-2i complex64和complex128,对应float32和float64浮点数精度

   // 内置的complex函数用于构建复数
   var x complex64 = complex(1, 2)
   var y complex128 = complex(3, 4)
   var z complex128 = complex(5, 6)

   fmt.Println("x = ", x) // x =  (1+2i)
   fmt.Println("y = ", y) // y =  (3+4i)
   fmt.Println("z = ", z) // z =  (5+6i)

   // 内建的 real 和 imag 函数分别返回复数的实部和虚部
   fmt.Println("real(x) = ", real(x)) // real(x) =  1
   fmt.Println("imag(x) = ", imag(x)) // imag(x) =  2
   fmt.Println("y * z =", y*z)        // y * z =  (-9+38i)

}