Go语言基础 -- 数据类型(int,float,char,string,指针,)


基本数据类型

数值型

整数不同类型的取值范围

有符号:int,int8(8位,byte是int8的别名),int16,int32(rune是int32的别名,表示一个unicode码点),int64
无符号:uint,uint8,uint16,uint32,uint64

有符号

整数类型,就是用于存放整数值的,比如0,-1,234等等

说明:
例如:int8,表示此数据类型占用空间为8位(1字节),
第一位,符号位,0表示无符号,1表示有符号,
剩余的7位表示数值,所以表示范围为2的-7到2的7次方-1(减得那个1是0),对于0表示时会有正0和-0,其实都是0所以负数部分就多了1个可以表示的数值

无符号


无符号的整数,特点是没有符号,所以第一位也可以表示数值本身,范围比有符号的要大一些,从0开始

其他的数值类型

整数型的使用细节
  1. Golang各整数类型分为:有符号和无符号,int uint的大小和操作系统有关
  2. golang的整形默认声明为int型
  3. 如何在程序查看某个变量的字节大小和数据类型

fmt.Printf("n1的类型为:%T",n1),查看变量的类型(%T)
fmt.Printf("n1占用的字节数是:%d",n1,unsafe.Sizeof(n1)),查看变量的所占用的字节数
  1. golang程序中整型变量在使用时,遵守保小不保打的原则,即:在保证程序正确运行下,尽量使用占用空间小的数据类型,如年龄,不会为负数,最大为130+ 所以选用uint8(byte)最为合适
  2. bit:计算机中的最小存储单位,byte:计算机中基本存储单元,1byte = 8bit

浮点类型

存放小数,比如1.2,0.32

float32,float64


说明:

  1. 浮点数在机器中存放的方式:浮点数=符号位+指数为+尾数位
3.56
11110000111.11111111111111111000


科学计数法
7.809..*10的6次方
2. 尾数部分可能丢失,造成精度损失.(-123.0000901)

float64的精度比float32的精度更准确,如果要保存一个精度高的数应该选用float64
3. 浮点型的存储分为三部分:符号位+指数位+尾数位,在存储过程中,精度会有丢失

使用浮点型注意事项
  1. golang浮点类型有固定的范围和字段长度,不受具体OS(操作系统)的影响
  2. goalng的浮点型默认声明为float64类型
  3. 浮点型常量有两种方式表示
    1). 十进制数形式:如:5.12 0.512可以用.512表示(必须有小数点)
    2). 科学计数法形式:如:5.1234e2 = 5.12*10的2次方 5.12E-2=5.12/10的2次方
    4.通常情况下应该使用float64,因为它比float32更准确

字符类型(char)

Go语言中没有专门的字符型,如果要存储单个字符(字母),一般使用byte来保存

字符串就是一串固定长度的字符连接起来的字符序列. Go的字符串是由单个字节链接起来的,也就是说对于传统的字符串是由字符组成的,而Go的字符串不同,它是由字节组成的


说明:当输出byte值时,就是输出了对应的ASCII码值
如果希望输出对应的字符:用格式化输出

fmt.Printf("c1=%c c2=%c",c1,c2)

如果是汉字的话,需要看值是否在byte的码值范围内

overflow溢出,处理方式

输出汉字对应的码值

说明:
1.如果保存的字符在ASICC表中,比如[0-1,a-z,A-Z],可以保存到byte中
2.如果保存的字符对应码值大于255,这时考虑用int类型保存
3.如果需要按照字符的方式输出,而不是码值,只是需要格式化输出,即fmt.Printf("%c",c1)

字符类型使用的注意事项

1.字符常量是用单引号('')引起来的单个字符,
例如:var c1 byte = 'a'
var c2 int = '中'
var c3 byte = '9'
2.Go中允许使用转义字符''来讲其后的字符转变成特殊字符型常量
例如:
var c3 char = '\n' //'\n'表示换行符

3.Go语言的字符使用UTF-8编码
4.在Go中字符的本质是一个整体,直接输出时,是该字符对应的UTF-8编码的码值
5.可以直接给某个变量赋一个数字,然后按格式化输出时%c会输出改数字对应的Unicode字符
6.字符类型是可以进行运算的,相当于一个整数,因为它都对应有Unicode码

字符类型的本质

1.字符型存储到计算机中,需要将字符对应的码值(整数)找到
存储:找到汉字对应的码值,转成二进制,存储
读取:二进制转成码值,通过码值到utf8对照表中找到对应的字符,读取
2.字符和码值的对应关系是通过字符编码表决定的(规定死的)
3.Go语言的编码都统一成了utf-8,非常的方便,很统一,再也没有编码乱码的问题

布尔型

布尔类型也叫bool类型,只允许取值true和false,占用1字节,通常用于逻辑运算,流程控制

字符串

官方将string归属到基本数据类型

字符串就是一串固定长度的字符连接起来的字符序列,Go的字符串是由单个字节链接起来的,Go语言的字符串的字节的字节使用UTF-8编码表示Unicode文本

package main

import "fmt"

func main()  {
	var address string = "背景你好"
	fmt.Println(address)
}

字符串使用细节

1.Go语言的字符串的字节使用UTF-8编码表示Unicode文本,这样Golang同意使用UTG-8编码乱码问题不会再成为困扰
2.字符串一旦赋值,字符串就不能修改了,在Go中字符串是不可变的

package main

import (
	"fmt"
	"unsafe"
)

func main()  {
	var address string = "背景你好"
	address[0] = "我不好"  // 不可改变字符串中的某个元素
        address = "我不好"    // 可以重新赋值
	fmt.Println(address,unsafe.Sizeof(address))
}
# cannot assign to address[0] (strings are immutable)

3.字符串的表示方法有两种
1).双引号,会识别\这种转义字符
2).反引号`,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止共计,或者输出源代码等效果
4.字符串拼接方式

package main

import (
	"fmt"
)

func main()  {
	var address string = "背景你好"
	var age string = "18"
	var address_age = address + age
        // address += age
        // fmt.Println(address)
	fmt.Println(address_age)
}
  1. 当字符串的长度太长是,需要使用到多行字符串,注意需要将+保留在上一行,因为编译器会自动加分号
    不保留在上一行,会表示这一行代码结束了,下一行代码就会有错
package main

import (
	"fmt"
)

func main()  {
	var address string = "背景你好" +
		"今天"
        // var address string = "背景你好" 
               // + "今天"  //错误!!! 
	fmt.Println(address)
}

基本数据类型的默认值.

在Go中,数据类型都有一个默认值,当没有赋值时,就会保留其默认值,在Go中的默认值又叫做零值

基本数据类型的转换

Golang和java/c 不同,Go在不同类型的变量之间赋值时需要显示转换(强制转换),也就是说golang中数据类型不能自动转换
表达式为:T(v)
将值v转换为类型T
T:就是数据类型,比如int32,int64,float32等等
v:就是需要转换的变量

package main

import (
	"fmt"
)

func main()  {

	var str_num int = 1
	int_num := int32(str_num)

        var float_num = 3.125
	var new_float_num float32 = float32(float_num)
	fmt.Println(int_num,new_float_num)
}
package main

import (
	"fmt"
)

func main()  {

	var str_num int = 1

	int_num := float64(str_num)
	fmt.Println(int_num)
}

数据类型转换注意事项

1.Go中,数据类型的转换可以从表示范围小->表示范围打,表示范围打->表示范围小
2.被转换的是变量存储的数据(即值),变量本身的数据类型并没有变化!

3.在转换中,比如将int64转成int8,编译时不会报错,只是转换的结果是按溢出处理(得到一个和希望结果不一样的值)

注意


编译无法通过

如何修改代码可以正确?(go语言不支持自动转换数据类型,需要强转类型)

基础数据类型和string的转换

在程序开发中,经常需要将基本数据类型转换成string类型,或者将string类型转成基本数据类型

基本数据类型转string

方式:
1.fmt.Sprintf("%参数",表达式)
1).参数需要和表达式的数据类型相匹配
2).fmt.Sprintf()会返回转换后的字符串

package main

import (
	"fmt"
)

func main() {

	var str1_num int = 1000
	var str2_num float64 = 154.24554
	var str3_num bool = true
	var str4_num byte = 'h'
	var str string // 空的字符串

	str = fmt.Sprintf("%d", str1_num)
	str = fmt.Sprintf("%d", str2_num)
	str = fmt.Sprintf("%t", str3_num)
	str = fmt.Sprintf("%w", str4_num)
	fmt.Printf("str1_num 转换后的 type (%T) is %q\n", str, str)
	fmt.Printf("str2_num 转换后的 type (%T) is %q\n", str, str)
	fmt.Printf("str3_num 转换后的 type (%T) is %q\n", str, str)
	fmt.Printf("str4_num 转换后的 type (%T) is %q", str, str)
}

2.使用strconv包的函数

package main

import (
	"fmt"
	"strconv"
)

func main() {

	var str1_num int = 1000
	var str2_num float64 = 154.24554
	var str3_num bool = true
        var str4_num int = 123
        var str4_num int64 = 456
	
	var str string // 空的字符串

	str = strconv.FormatInt(int64(str1_num),2) // int64转成二进制的字符串
	fmt.Printf("str1_num(%T) 转换后为 %q\n",str,str)

	str = strconv.FormatFloat(str2_num,'f',10,64)  // float转成10位的float64的字符串
	fmt.Printf("str1_num(%T) 转换后为 %q\n",str,str)

	str = strconv.FormatBool(str3_num)  // bool 转成 字符串
	fmt.Printf("str1_num(%T) 转换后为 %q\n",str,str)

        str = strconv.Itoa(str4_num)  // int类型很方便的转换成字符串
	fmt.Printf("str (%T) 转换后为%q",str,str)

        str = strconv.Itoa(int(str5_num))  // int64必须转成int,才可以用这个函数
	fmt.Printf("str (%T) 转换后为%q",str,str)

}

string转成基本数据类型

package main

import (
	"fmt"
	"strconv"
)

func main() {

	var str1 string = "true"
	var str_to_bool bool
	str_to_bool , _ = strconv.ParseBool(str1)
	fmt.Printf("str_to_bool (%T) 转换成%q\n",str_to_bool,str_to_bool)

	var str2 string = "123456"
	var str_to_int int64
	var str_to_int2 int
	str_to_int , _ = strconv.ParseInt(str2,10,64) // 只能转成int64,如果是int需要强转
	str_to_int2 = int(str_to_int)
	fmt.Printf("str_to_bool (%T) 转换成%v\n",str_to_int2,str_to_int2)

	var str3 string = "12.1254"
	var str_to_float float64

	str_to_float , _ = strconv.ParseFloat(str3,64)
	fmt.Printf("str_to_float (%T) 转换成%v",str_to_float,str_to_float)

}

说明: 因为返回的是int64或者float64,如果希望得到int32或float32,用int32()/float32()强转一下

注意事项

在将string类型转换成基本数据类型时,要确保string类型能够转成有效的数据,比如可以吧"123"转成一个整数,但是不能把"hello" 转成一个整数,如果这样做,Golang 直接将其转换成0,其他所有转不成功的数据类型都会置其为默认值

派生/复杂数据类型

指针(pointer)

基本介绍

1.基本数据类型,变量存的是值,也叫值类型
2.获取变量的地址,用&,比如:var num int,获取num的地址:&num

var i int = 100
fmt.Printf("i的内存地址为",&i)

3.指针类型,变量存的是一个地址,这个地址指向的空间存的才是值,比如var ptr *int=&num

package main

import "fmt"

func main() {
	var i int = 100
	fmt.Printf("i的内存地址为%v\n",&i)

	// xx是一个指针变量,类型是*int,并且指向i的内存地址,内存地址指向的才是值
	var xx *int = &i
	// 指针变量也是有自己的内存地址的
	fmt.Printf("xx指向的内存地址为%v\n",xx,)
	fmt.Printf("xx指针变量的内存地址为",&xx)
}

4.获取指针类型所指向的值,使用:*,比如var ptr int,使用ptr获取p指向的值

package main

import "fmt"

func main() {
	var i int = 100
	fmt.Printf("i的内存地址为%v\n",&i)

	// xx是一个指针变量,类型是*int,并且指向i的内存地址,内存地址指向的才是值
	var xx *int = &i
	// 指针变量也是有自己的内存地址的
	fmt.Printf("xx指向的内存地址为%v\n",xx,)
	fmt.Printf("xx指针变量的内存地址为%v\n",&xx)
	fmt.Printf("xx指针变量指向的值为",*xx)
}

练习

题目:
1.写一个程序,获取int变量num的地址,并显示到终端
2.将num的地址赋给指针ptr,并通过ptr去修改num的值

package main

import "fmt"

func main() {
	var num int = 500
	fmt.Printf("i的内存地址为%v\n",&num)

	var ptr *int = &num
	*ptr = 500
	fmt.Printf("改变后的值为num=",num)
}

指针的注意事项

1.值类型,都有对应的指针类型,形式为*数据类型,比如int的对应的指针就是int,float32 对应的指针类型就是float32,依次类推
2.值类型包括:基本数据类型int系列,float系列,bool,string,数组和结构体(struct)

值类型和引用类型

值类型和引用类型在go中都有哪些数据结构

1.值类型:基本数据类型int系列,float系列,bool,string,数组和结构体struct
2.引用类型:指针,slice切片,map,管道channel,接口(interface)等都是引用类型

区别

1.值类型,变量直接存储值,内存通常在栈中分配

2.引用类型,变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆上分配.当没有任何变量引用这个地址时,该地址对应的数据空间就变成为一个垃圾有GC来回收


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM