前言

程序=数据+指令(算法)所以数据结构就是帮我们 解决  如何在程序开发过程  定义和存储要用到的数据;

Go语言的数据类型拥有丰富的数据类型

 

 

 

 

整型

.\main.go:8:21: constant 1000 overflows uint8

在Python里面定义1个数字类型的变量,无需考虑系统底层内存存储这个变量 需要开销多大 存储空间(位),因为Python解释器自动计算、分配;

在Go里面不行!Go语言的整型分为有符号整型和无符号整型2大类。

计算机只认识0、1,所谓有符号和无符号就是 计算机到底需要分配多大的存储空间(位/字节)来存储这些数字。

有符号整型:计算机使用第0位表示数字的 +正 -负性质,其他位用来表示数字。(可表示负数,但是表示正数的范围小!)

无符号整型:计算机使用全部的位 来表示数字(不可以表示负数,但是可表示正数的范围很大!)

综上所述:

有符号整型:表示数字的位 比无符号少了1位,所以有符号整型可表示负数,但是表示正数字范围小。

无符号整型:没有符号位无法表示负数,但是表示正数的范围会更大。

 

所有我们需要根据数字的大小范围来选择合适的整数的类型

 

注意即便uint8和uint20同属于整型和无符号整型,也有不同数据类型之分。

 

 

有符号整型:

 

 

int8、int16、int32、int64

 

无符号整型:

 

uint8、uint16、unit32、uint64

 

 

不同整型之间的相互转换

在go语言中不同位的整型相互转换时,由低位转成高位,不会有问题,但是由高位转换成低位就会表示错误。

func main() {
  var v1 int8=10
  var v2 int16=19
  //整型数据类型转换
  v3:=int16(v1)+v2
  fmt.Println(v3,reflect.TypeOf(v3))//29 int16
  //低位转向高位,没问题。高位转低位无法转
  var v4 int16 = 2020
  v5:=int8(v4)
  fmt.Println(v5)//注意这里不会报错,而是轮回转换。
}

 

整型和字符串之间的转换(strconv)

 使用strconv.Atoi(string)可以把字符转换成整型,trconv.Itoa(int)把数字转换成字符串。

 //2.整型和字符串类型之间的的转换
    var str1 string ="132201988666"
    fmt.Println(strconv.Atoi(str1))
    number2:=13220198866
    //strconv.Itoa()只能转换int类型
    fmt.Println(strconv.Itoa(number2))

 

不同进制之间的转换

人类使用10进制计算,计算机使用二进制(一大堆0和1)进行运算。

通常计算机使用八进制和十六进制去更精简地显示二进制给人类看。 

既然人类熟悉10进制,那么把二进制转换成10进制给人类显示,岂不更方便?

因为10进制不如8进制和16进制那样,在计算机中方便运算。

 

 1.十进制(整型)转换成 二进制、八进制、十六进制

 在go语言中十进制是以整型的方式存在,其进制(二进制、八进制、十六进制)均已字符串的形式存在。

	var n1 int64 =190
	//十进制转换成二进制
	binaryNumber:=strconv.FormatInt(n1,2)
	fmt.Println(binaryNumber)//string
	fmt.Println(reflect.TypeOf(binaryNumber))
	//十进制转换成8进制
	octalNumber:=strconv.FormatInt(n1,8)
	fmt.Println(octalNumber)//string
	fmt.Println(reflect.TypeOf(octalNumber))
	//十进制转成16进制
	hexadecimalNumber:=strconv.FormatInt(n1,16)
	fmt.Println(hexadecimalNumber)
	fmt.Println(reflect.TypeOf(hexadecimalNumber))//string

 

2.二进制、八进制、十六进制(字符串)转换成十进制(int64位整型)  

我们使用strconv.Format(十进制,想要的进制 ),可以把十进制(整型)转成二进制、八进制、十六进制的字符串。

使用strconv.ParseInt(), 把二进制、八进制、十六进制(字符串)转换成十进制(整型)。

    var barnaryNumber,octalNumber,hexadecimalNumber string ="10111110","276","be"
    fmt.Println(strconv.ParseInt(barnaryNumber,2,16))
    //2:把字符串barnaryNumber当做二进制去转换成十进制,
    //16:转换过程中对十进制结果数字大小范围进行约束
    //result永远以int64的类型返回
    fmt.Println(strconv.ParseInt(octalNumber,8,16))
    fmt.Println(strconv.ParseInt(hexadecimalNumber,16,16))

 

 常见的数学运算

package main

import (
    "fmt"
    "math"
)

func main() {
    fmt.Println(math.Abs(-19))    //获取绝对值:19
    fmt.Println(math.Floor(3.14)) //向下取整
    fmt.Println(math.Ceil(3.14))  //向上取整
    fmt.Println(math.Round(3.1678)) //自动(四舍五入)取整数
    fmt.Println(math.Round(3.1678*100)/100)//自动保留小数点后2位
    fmt.Println(math.Mod(11, 3))  //获取余数
    fmt.Println(math.Pow(2, 2))   //求2的2次方
    fmt.Println(math.Pow10(2))    //求2的10次方
    fmt.Println(math.Max(3, 5))   //获取较大
    fmt.Println(math.Min(3, 5))   //获取较小

}

 

超大数值整型

当我们要使用的数字超过了64位可以表示的范围,可以使用big.Int。

package main

import (
    "fmt"
    "math/big"
)

func main() {
    /*
    //1.创建1个超大整型的对象
    var v1 big.Int
    //var v2 *big.Int
    v3:=new(big.Int)
    //2.在超大整型对象中写入1些值
    v1.SetInt64(1993)
    //支持以字符串的形式写入到内存,以10进制的形式
    v1.SetString("9012308480889",10)
    v3.SetString("10000000000000000000",10)
    fmt.Println(v1,v3)
     */
    //3.超大整型操作(加减乘除)
    n1:=new(big.Int)
    n1.SetString("19999999991111",10)
    n2:=new(big.Int)
    n2.SetString("7777777777",10)
    result:=new(big.Int)
    //+
    result.Add(n1,n2)
    fmt.Println(result)
    //-
    result.Sub(n1,n2)
    fmt.Println(result)
    //*
    result.Mul(n1,n2)
    fmt.Println(result)
    //
    result.Div(n1,n2)
    fmt.Println(result)
    //除:得到商和余数 求页码时使用
    minder:=new(big.Int)
    result.DivMod(n1,n2,minder)
    fmt.Println(result,minder)
    //把bigint转换成int64
    fmt.Println(result.Int64())
    //把bigint转换成字符串
    fmt.Println(result.String())

}

 

 int、uint、rune、byte

 

 

在Go语言中数字的默认数据类型是int类型,也就是有符号整型,如果是32的操作系统就是int32如果是64位操作系统就是int64

 

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	var n1 = 100
	//n1的数据类型:int n1占用的字节数是8我的电脑是64位所以就是 int64 8位=1字节=8字节
	fmt.Printf("n1的数据类型:%T n1占用的字节数是%d \n", n1, unsafe.Sizeof(n1))
	//在程序运行中,尽量使用占用空间减少的数据类型 比如年龄的数字范围1-200足矣,不需要用int64
	var age byte = 19
	println(age)

}

  

整型变量的声明方式

为什么每中编程语言都有数据类型?

就是可以满足我们声明多样化的数据结构变量的需求,我们的程序逻辑可以处理各种各样的变量(数据)时,我们就可以完成更多的功能。

package main
import "fmt"
func main(){
	//方法1:先声明再赋值
	var n1 int32
	n1=10
	//方法2:var 声明时一起赋值
	var n2 int8 =10
	//方法3:简短声明自动推断19为默认为int类型
	n3:=18
	//方法4:int类型强制转换为int16
	var n4=int16(19)
	fmt.Printf("%T,%T,%T,%T",n1,n2,n3,n4)

}

  

 

浮点型

Go语言提供了2种浮点型float32和float64, 默认使用float64。 单fudi

float32

float64  

 

我们平时使用的这些编程语言处理小数时 表示是不精准的。

JavaScript

Python

 Golang

v1:=0.1
v2:=0.2
fmt.Println(v1+v2) //0.30000000000000004 

 

浮点型为什么无法精准表示?

计算机只认识0和1,想要明白这个问题,得说到浮点型是怎么转换成二进制进行存储的。

例如:声明1个变量   var price float32 =39.29

第一步:把浮点型 39.29转换成二进制

整数部分(39/十进制)直接转换成二进制:39----->100111

小数部分:让小数乘2,结果小于1则继续乘2,如果大于1则让结果减1再继续乘2,一直等到*2=1则结束。

得出浮点型,小数部分的二进制

结果的整数部分拼接起来,所以0.29的二进制就是---->01001010001111010111000........................

问题就出在这:39.29的小数部分0.29,这特么永远得不出1,导致fraction位无法完整存储浮点型小数部分的二进制!丢失精度了!

但是有的小数是可以的例如:0.5所以并不是所有小数都会出现精度丢失的问题。

经过以上步骤39.29的二进制就100111.01001010001111010111000........................

第二步:科数据计数法表示二进制

科数计数法就是把1个数字变成1.x乘2的多少次方。向左移了几位就是2的几次方,如果向右移了几位就是2的负几次方。

科数计数法发表示:100111.01001010001111010111000........................

第三步:存储到科学计数法表示的二进制

以flaot32位进行表示

sign:表示浮点型的正负,0表示正数、1表示负数

exponent(指数):存储科学技术法的指数(几次方),exponent有8位所以表示范围=-128至127,这8位既可以表示负指数  也可以表示正值数。

例如:指数是5 那么5得+127。

为什么+5得加127,因为如果再来个是1个-5,岂不是和+5表示重叠了!

5+127=132转换乘二进制10000100存储到exponent.

fraction(小数):存储浮点型小数部分二进制的01001010001111010111000........................超出32/64位直接丢弃!这就是浮点型无法精确表示的原因。

 

 

decimal第三方包精确表示浮点型

尤其是面向电商领域开发,特别需要浮点型。

你就不得不解决浮点型精度丢失的问题,golang的decimal包可以解决这个问题。

package main

import (
    "fmt"
    "github.com/shopspring/decimal"
)

func main() {

    var v1 =decimal.NewFromFloat(0.0000019)
    var v2 =decimal.NewFromFloat(0.298766)
    var v3 =v1.Add(v2)
    var v4 =v3.Sub(v2)
    var v5 =v4.Mul(v2)
    var v6 =v4.Div(v1)
    fmt.Println(v3)
    fmt.Println(v4)
    fmt.Println(v5)
    fmt.Println(v6)
    var price=decimal.NewFromFloat(3.6615926)
    fmt.Println(price.Round(1)) //保留小数点后1位自动四舍五入
    fmt.Println(price.Truncate(2))//保留小数点后2位不需要四舍五入



}

 

复数

coplex128

complex64

 

布尔值

Go里面的布尔值不能像Python那样和0和1做转换

true

false

func main() {
    //字符串转换成布尔类型
    // "1", "t", "T", "true", "TRUE", "True"都可以转换成true
    //"0", "f", "F", "false", "FALSE", "False" 都可以转换成false
    reslut,err:=strconv.ParseBool("True")
    fmt.Println(reslut,err)
    //布尔类型转换成字符串
    reslut1:=strconv.FormatBool(true)
    fmt.Println(reslut1)
}

 

字符 

Go语言的字符有以下两种:

  • 一种是 uint8 类型,或者叫 byte 型,代表了 ASCII 码的一个字符的编码。 
  • 另一种是 rune 类型,代表一个 UTF-8 字符的编码,当需要处理中文、日文或者其他复合字符时,则需要用到 rune 类型。rune 类型等价于 int32 类型

 

字符串

Go的字符串是由Utf-8编码之后的字节序列,所以不能修改,1个汉字占用3个字节、1个英文字母占用1个字节的存储空间。

go使用rune(1个int32类型的数字) 表示中文字符,使用byte(1个uint8类型的数字)表示英文。

字节切片和rune切片的区别是:

rune切片直接存储Unicode(ucs4)中字符串对应的码位,字节切片则存储码位被utf-8编码之后的utf8码。

 

package main

import (
    "fmt"
    "strconv"
    "unicode/utf8"
)

func main() {
    //1.go语言中的字符串本质上是utf-8编码之后的字节序列
    var name string="张根"
    fmt.Println(name)
    //utf-8的第三个模板:1110XXXX 10XXXXXX 10XXXXXX
    //张 utf-8码=根据张字符在Unicode的码位codepoint进行utf-8编码所得 1110【0101】 10【111100】 10【100000】
    fmt.Println(strconv.FormatInt(int64(name[0]),2),strconv.FormatInt(int64(name[1]),2),strconv.FormatInt(int64(name[2]),2))  //
    //根 utf-8码=根据张字符在Unicode的码位codepoint进行utf-8编码所得 11100110 10100000 10111001
    fmt.Println(strconv.FormatInt(int64(name[3]),2),strconv.FormatInt(int64(name[4]),2),strconv.FormatInt(int64(name[5]),2))


    //2.获取字符串的长度其实就是获取utf-8编码之后字节的长度。即6个字节
    fmt.Printf("字节长度%d\n",len(name))

    //3.字符串转换成---》1个字节切片
    byteSlice:=[]byte(name)
    fmt.Println(byteSlice)

    //4.字节切片转换成----》1个字符串
    togetByteSlice:=[]byte{229,188,160,230,160,185}
    togetString:=string(togetByteSlice)
    fmt.Println(togetString)

    //5.rune也是golang里的1种数据类型:它表示的的是字符串在Unicode(ucs4)字符集中对应的码位
    runeSet:=[]rune(name)  //[24352 26681]
    fmt.Println(runeSet)
    //张 在Unicode字符集中的码位:二进制:10111110  0100000 十六进制:5f20
    //utf-8编码的机制:(101)(111100)(100000)--->1110XXXX 10XXXXXX 10XXXXXX  --->1110【0101】 10【111100】 10【100000】
    fmt.Println(strconv.FormatInt(int64(runeSet[0]),2))
    fmt.Println(strconv.FormatInt(int64(runeSet[0]),16))
    //根 在Unicode字符集的的码位:二进制:11010000 0111001    十六进制:6839
    fmt.Println(strconv.FormatInt(int64(runeSet[1]),2))
    fmt.Println(strconv.FormatInt(int64(runeSet[1]),16))

    //6.rune切片转换成字符串
    runeList:=[]rune{24352,26681}
    fmt.Println(string(runeList)) //张根

    //7.获取字符串的字面长度 牛魔王 3个长度
    nickName:="牛魔王"
    runeLenth:=utf8.RuneCountInString(nickName)
    fmt.Println(runeLenth)

}
golang字符串底层实现原理

 

 

Python字符串的index方法:

a="1111"
print((a.index("2")))

#找不到指定的元素Python报错:ValueError: substring not found

Golang字符串中的strings.index()方法:

package main

import (
	"fmt"
	"strings"
)

func main() {
	testString := "Hello"
	index := strings.Index(testString,"W")
	fmt.Println(index)//找不到指定元素返回-1
}

 

practice

自定义1个string的split方法

package main

import (
	"fmt"
	"strings"
)

func main() {
	str1 := "123a456a789"
	sep := "a"
	var ret []string
	//a的index
	index := strings.Index(str1, sep)
	//知道字符串中不包含a也就是index=-1为止
	for index >= 0 {
		//a位置之前的部分:123
		ret = append(ret, str1[:index])
		//a位置之后的部分:456a789
		str1 = str1[index+1:]
		index = strings.Index(str1, sep)
	}
	ret = append(ret, str1)
	fmt.Println(ret)

}

 

 

字符串相关操作

go中字符串相关的操作的API都封装在strings包中

package main

import (
    "bytes"
    "fmt"
    "reflect"
    "strconv"
    "strings"
    "unicode/utf8"
)

func main() {
    //1.获取字符串的字面长度
    name:="张根"
    fmt.Println(utf8.RuneCountInString(name))
    //2.判断字符串开头?
    if strings.HasPrefix(name,""){
        fmt.Print("我姓张")
    }
    //3.判断字符串结尾?
    if strings.HasSuffix(name,""){
        fmt.Print("名根。\n")

    }
    //3.判断字符串是否包含?
    str1:="抬老子的意大利炮来。"
    if (strings.Contains(str1,"老子")){
        fmt.Println("别说脏话!")
    }
    //4.字符串小大写转换:验证码对大小写不敏感
    realName:="Martin"
    upperName:=strings.ToUpper(realName)
    fmt.Println(upperName)
    LowerName:=strings.ToLower(upperName)
    fmt.Println(LowerName)

    //5.去除2边、 前缀、后缀
    string2:="ABC"
    result2:=strings.TrimRight(string2,"C")
    fmt.Println(result2)
    result3:=strings.TrimLeft(string2,"A")
    fmt.Println(result3)
    string3:=" ABC"
    //ps.去除两端的空格:在Python和JS中trim()没有参数自动去除空,但是go语言需要,写上空字符串
    result4:=strings.Trim(string3," ")
    fmt.Println(result4)

    //6.字符串替换
    string4:="zhanggen"
    //从左到右找到第1个进行替换
    result5:=strings.Replace(string4,"g","G",1)
    fmt.Println(result5)
    //从左到右找到前2个”g“进行替换
    result6:=strings.Replace(string4,"g","G",2)
    fmt.Println(result6)
    //替换所有“2”
    result7:=strings.Replace(string4,"n","N",2)
    fmt.Println(result7)

    //7.字符串分割成string切片
    string5:="1 2 3"
    result8:=strings.Split(string5," ")
    fmt.Println(result8,reflect.TypeOf(result8)) //[]string

    //8.字符串拼接
    //+不建议
    message:="我爱北京"+"天安门"
    fmt.Println(message)
    //效率高一些
    stringList:=[]string{"","","北京"}
    result9:=strings.Join(stringList,"")
    fmt.Println(result9)
    //效率更高一些: go 1.10之前
    var buffer bytes.Buffer
    buffer.WriteString("我爱")
    buffer.WriteString("北京")
    buffer.WriteString("天安门")
    result10:=buffer.String()
    fmt.Println(result10)
    //效率更高一些: go 1.10之后
    var builder strings.Builder
    builder.WriteString("我爱")
    builder.WriteString("")
    builder.WriteString("")
    result11:=builder.String()
    fmt.Println(result11)

    //9.字符串和整型之间相互转换:Atoi/ItoO
    var message1 string ="666"
    number,err:=strconv.Atoi(message1)
    if err==nil{
        fmt.Println(number,reflect.TypeOf(number))
    }
    fmt.Println(strconv.Itoa(number),reflect.TypeOf(strconv.Itoa(number)))
    //字符串转数字:64:转换过程中对十进制结果数字大小范围进行约束
    number1,err:=strconv.ParseInt("1111000",2,64)
    fmt.Println(number1,err,reflect.TypeOf(number1))
    //10进制转2进制
    decimalDigit:=strconv.FormatInt(int64(120) ,2,)
    fmt.Println(decimalDigit)

    //10.字符串和字节切片之间的转换
    name2:="张纪中"
    //字符串转换成字节集合:字节切片本质上是二进制但是以10进制的方式显示出来。
    byteSet:=[]byte(name2)
    fmt.Println(byteSet)
    //字节集合转换成字符串
    byteList:=[]byte{229,188,160,231,186,170,228,184,173}
    fmt.Println(string(byteList))

    //11.字符串和rune切片之间的转换
    name3:="张艺谋"
    runeSet:=[]rune(name3)
    fmt.Println(runeSet)
    //rune int32的别名
    runeSlice:=[]rune{24352,33402,35851}
    fmt.Println(string(runeSlice))
    fmt.Println()

    //12.string和字符:根据Unicode的码位进行转换(应用生产随机验证码)
    v1:=string(26681)
    fmt.Println(v1,reflect.TypeOf(v1))
    //字符串转数字
    v2,size:=utf8.DecodeRuneInString("A")
    fmt.Println(v2,size) //65 1个字节表示1个英文字符
    v3,size:=utf8.DecodeRuneInString("")
    fmt.Println(v3,size) //26681 3个字节表示1个汉字



}
字符串常见操作

 

package main

import (
	"fmt"
	"strings"
	"unicode"
)

func main() {
	s1 := "D:\\goproject\\src"
	//字符相关操作
	//字符串长度
	fmt.Println(len(s1))

	//字符串拼接
	FirstName := "Martin"
	LastName := "Zhang"
	FullName := FirstName + LastName
	fmt.Println(FullName)
	FullName2 := fmt.Sprintf("%s%s", LastName, FirstName)
	fmt.Println(FullName2)

	//字符串分割
	s3 := "D:\\goproject\\src"
	ret := strings.Split(s3, "\\")
	fmt.Println(ret)
	//包含
	fmt.Println(strings.Contains(s3, "D"))

	//判断字符串 的开头和结尾判断
	fmt.Println(strings.HasPrefix(s3, "D"))
	fmt.Println(strings.HasSuffix(s3, "src"))

	//判断字符在字符串中的index
	s2 := "abcdeb"
	fmt.Println(strings.Index(s2, "b"))
	fmt.Println(strings.LastIndex(s2, "b")) //最后1次出现的位置

	//字符串拼接
	s4 := "D:\\goproject\\src"
	ret4 := strings.Split(s4, "\\")
	s5 := strings.Join(ret4, "/")
	fmt.Println(s5)

	//字符串表里
	//字符:组成字符串的每1个元素 我们称之为字符,在go语言里通过''单引号来定义字符
	//在go语言里字符分为2种:1种是byte 1种是rune
	//byte:给ascii 编码的字符起的别名
	//rune:给Unicode编码的字符起的别名
	var c1 byte = 'c'
	var c2 rune = '中'
	fmt.Printf("c1:%T c2:%T\n", c1, c2)
	s6 := "hello 张根"
	//for 循环 按照1个字节循环(会出现乱码:因为中文和英文占用的字节不一致)
	// for i := 0; i < len(s6); i++ {
	// 	fmt.Printf("%c\n", s6[i])
	// }
	//for range 按1个字符循环
	for _, v := range s6 {
		fmt.Printf("%c\n", v)

	}

	//字符串修改
	s7 := "白萝卜"
	s8 := []rune(s7) //把字符串强制转换为runne切片就可以修改字符串了
	s8[0] = '红'      //修改第一个字符
	fmt.Println(string(s8))

	//类型转换
	n := 10
	var f float64
	f = float64(n) //整型 转成 float64类型
	fmt.Println(f)
	fmt.Printf("%T\n", f) //float64

	//判读数据类型

	s9 := "Hello张根"
	for _, v := range s9 {
		if unicode.Is(unicode.Han, v) {
			fmt.Print(string(v))
		}
	}

}

 

 字符串的索引和循环遍历

Golang的字符串和Python中的字符串存储机制上有很大区别,Python中的字符串直接是Unicode中的字符,直接同过索引获取即可。(学的这里我仿佛感受到了Python其实帮我们做了很多很多事情....)

Golang中字符串是utf-8编码之后的字节序列,所以我们通过索引获取到的是字节(其实是一堆utf-8编码之后的0和1,显示是按10进制显示出来的)并非字符本身。

runn 切片可以帮我们解决这种问题,如果把1个字符串转换成rune切片那么这个rune切片中就存储了字符串中每1个字符在Unicode字符集中对应的码位。

既然得到每1个字符的码位 就好比1个工作在凌晨3点的程序员得到了老板让先下班回家的指令, 好比拿到了数据库里1个记录的index,string(codepoint)就可以拿到字符了。

 

package main

import "fmt"

func main() {
    //1.索引获取字节
    var name= "大根子"
    //获取字字节序列的第1个字节
    fmt.Println(name[0])
    //第2个
    fmt.Println(name[1])
    //第3个
    fmt.Println(name[2])
    //2.获取字节区间:获取3个字节
    fmt.Println(name[0:3]) //

    //3.循环获取蓑鲉字节
    for i:=0;i<len(name);i++{
        fmt.Println(i,name[i])
    }
    //4.for range获取所有字符,
    //for range字符串相当于把字符串转换成了rune切片,进行循环
    for index,item:=range name{
        fmt.Println(index,string(item))
    }

    //5.转成rune集合获取字符
    dataList:=[]rune(name)
    fmt.Println(dataList[0],string(dataList[0]))
}
字符串正确的索引和循环方式

 

 

 字符(char)

在Go中有字符的概念,使用单引号表示,需要注意的是,英文字符和中文字符,

Go 使用int 的 数据类型别名的方式来表示字符。其中rune为int32的数据类型别名表示中文byte为uint8的数据类型别名用于表示英文

 

什么是数据类型别名?

In a nutshell just an other name name data type of Golang by you like way.

。。...

package main

import "fmt"

var c1 byte = 'c'
var c2 rune = '中'

type myInt = int

func main() {
	var n myInt
	n = 100
	fmt.Printf("%T\n",n)//%T\n Myint还是int

	fmt.Printf("%T\n", c1) //uint8
	fmt.Printf("%T\n", c2) //int32

}

  

 

参考

posted on 2020-03-19 09:22  Martin8866  阅读(972)  评论(0编辑  收藏  举报