golang 基础之数据类型(上)

变量数据类型

image

整数类型

image

 int8 超出地址范围

package main
import "fmt"
func main(){
	var i int = 1
	fmt.Println("i=",i)
	var h int8 = -129

	fmt.Println(h)
}
// 执行结果
// PS D:\golang\goproject\src\src01\go_code> go run src\chapter03\demo05\main.go
// # command-line-arguments
// src\chapter03\demo05\main.go:7:15: cannot use -129 (untyped int constant) as int8 value in variable declaration (overflows)

  

 无符号 

image

 浮点型

基本介绍

golang的浮点类型可以表示一个小数,比如123.4,7.8,0.12

image

 

说明

1)关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位

示例

import (
	"fmt"
	// "unsafe"
)
func main(){

	var price float32 = 89.32
	fmt.Println("price=",price)
	var num1 float32 = -0.00089
	var num2 float64 = -76534567.09
	fmt.Println("num1=",num1)
	fmt.Println("num2=",num2)

}
// 执行结果
// price= 89.32
// num1= -0.00089
// num2= -7.653456709e+07

  

2)尾数位部分可能丢失,造成精度损失-123.0000901

示例

package main

import (
	"fmt"
	// "unsafe"
)
func main(){

	// var price float32 = 89.32
	// fmt.Println("price=",price)
	// var num1 float32 = -0.00089
	// var num2 float64 = -76534567.09
	// fmt.Println("num1=",num1)
	// fmt.Println("num2=",num2)
	var num3 float32 = -123.0000901
	var num4 float64 = -123.0000901
	fmt.Println("num3=",num3,"num4=",num4)
}
// 执行结果
//num3= -123.00009 num4= -123.0000901

  说明: flota64 精度比float32的要准确

       说明:如果希望保存一个精度高的数,则应该选择float64位

3)浮点型的存储分为三部分:符号位+指数位+尾数位在存储过程中,精度会丢失

浮点型使用细节

1)golang 浮点型有固定的范围和字段长度,不受具体OS的影响

2)golang 的浮点型默认声明float64类型

package main

import (
	"fmt"
	// "unsafe"
)
func main(){

	var  num5 = 1.1
	fmt.Printf("num5的数据类型是%T",num5)
}
// 执行结果
//num5的数据类型是float64

  

3)浮点型常量有两种表示形式

十进制数形式:如:5.12  .512 (必须有小数点)

package main

import (
	"fmt"
	// "unsafe"
)
func main(){

	num6 := 5.12
	num7 := .123
	fmt.Println("num6=",num6,"num7=",num7)
	 
}
// 执行结果
//num6= 5.12 num7= 0.123

  

科学计数法形式: 如:5.1234e2 = 5.12*10的2次方 5.12E-2 = 5.12/10的2次方

package main

import (
	"fmt"
	// "unsafe"
)
func main(){

	num8 := 5.1234e2//5.1234e2 *10的2次方
	fmt.Println("num8=",num8)

	 
}
// 执行结果
//num8= 512.34

  示例2

package main

import (
	"fmt"
	// "unsafe"
)
func main(){

	num8 := 5.1234e2//5.1234e2 *10的2次方
	num9 := 5.1234E2//5.1234e2 *10的2次方
	num10 := 5.1234E-2//5.1234e2 /10的2次方
	num11 := 5.1234e-2//5.1234e2 /10的2次方
	fmt.Println("num8=",num8,"num9=",num9,"num10=",num10,"num11=",num11)

	 
}
// 执行结果
//num8= 512.34 num9= 512.34 num10= 0.051234 num11= 0.051234

  

4)通常情况下,应该使用float64,因为它比float32更精确

 字符类型

基本介绍

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

package main

import "fmt"

func main(){
	var c1 byte = 'a'
	var c2 byte = '0'
	// 当我们直接输出byte值,就是输出了对应的字符的码值
	fmt.Println("c1=",c1)
	fmt.Println("c2=",c2)
	//如果我们希望输出对应字符,需要使用格式化输出
	fmt.Printf("c1 = %c c2 = %c\n", c1,c2)
	var c3 int = '北'
	fmt.Println("c3=",c3)
	fmt.Printf("c3=%c",c3)

}
// 执行结果
// c1= 97  
// c2= 48
//c1 = a c2 = 0
// c3= 21271
// c3=北

  说明:1)如果我们保存的字符在ASCII表的,比如[0~1,a-z,A-Z]直接可以保存到byte

                  2)如果我们保存的字符对应码值大于255,这时我们可以考虑使用int类型保存

       3)如果我们需要按照字符的方式输出,我们需要格式化输出即fmt.Printf("c3=%c",c3)

字符串就是一串固定长度的字符连接起来的字符序列,Go的字符串是由单个字节链接起来的,也就是说对于传统的字符串是由字符组成的,而go的字符串不同,是由字节组成[官方将string归属到基本数据类型]

字符类型使用细节

1)字符常量是用单引号''括起来的单个字符。例如var c1 byte = 'a' 

2) Go 中允许使用转义字符'\'来将其后面的字符转变为特殊字符型常量。例如,var c3 char = "\n" // '\n'表示换行符

3) Go 语言的字符使用UTF-8 编辑

4) 在Go中,字符的本质是一个整数,直接输出时,是该字符对应该的UTF-8编码的码值

5)可以直接给某个变量赋值一个数字,然后按格式化输出时%c会输出该数字对应的unicode

6) 字符类型是可以进行运算的,相当于一个整数,因为它对应有Unicode

 示例

package main

import "fmt"

func main(){
	var c1 byte = 'a'
	var c2 byte = '0'
	// 当我们直接输出byte值,就是输出了对应的字符的码值
	fmt.Println("c1=",c1)
	fmt.Println("c2=",c2)
	//如果我们希望输出对应字符,需要使用格式化输出
	fmt.Printf("c1 = %c c2 = %c\n", c1,c2)
	var c3 int = '北'
	fmt.Println("c3=",c3)
	fmt.Printf("c3=%c\n",c3)
	var c4 int = 230
	fmt.Printf("c4=%c\n",c4)
	var c5 int = '陈'
	fmt.Println(c5+10)

}
// 执行结果
// c1= 97  
// c2= 48
//c1 = a c2 = 0
// c3= 21271
// c3=北
// c4=æ
// 38482

  字符本质谈讨论

1)字符型: 存储到就计算机中,

 存储: 字符--->对应码值--->二进制--->存取

读取: 二进制--->码值--->字符--->读取

2)字符和码值的对应关系是通过字符编码决定的(是规定好的)

3)Go语言的编码都统一成了UTF-8.非常方便,很统一,再也没有编码的困扰

布尔类型

1)布尔类型也叫bool类型,bool类型数据只允许取值true 和false

2)  bool类型占1字节

3)boolean 类型适于逻辑运算,一般用于程序流程控制

if 条件控制语句

for 循环控制语句

package main

import (
	"fmt"
	"unsafe"
)

func main(){
	var b = false
	fmt.Println("b=",b)
	//1.bool 类型占用存储空间是1个字节
	fmt.Println("b的占用空间 =",unsafe.Sizeof(b))
	//2.bool 类型只能取true或者false
	


}
// 执行结果
// b= false
// b的占用空间 = 1

  字符串类型:string

基本介绍

字符串就是一串固定长度的字符连接起来的字符序列。go 的字符串是由单个字节连接起来的。go语言的字符串的字节使用UTF-8 编码标识Unicode

示例

package main

import (
	"fmt"
)

func main(){
	var address string = "北京长城 110 hello world!"
	fmt.Println(address)

}
// 执行结果
// 北京长城 110 hello world!

  注意细节

1)go 语言的字符串的字节使用UTF-8编码标识Unicode文本,这样golang统一使用UTF-8编码。乱码问题不会困扰程序员

2)字符串一旦赋值了,字符串就不能修改了,在go中字符串是不可变的。

3)字符串的两种表示形式

(1)双引号,会识别转义字符

(2)反引号,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果

package main

import (
	"fmt"
)

func main(){
	var address string = "北京长城 110 hello world!"
	fmt.Println(address)
	//字符串一旦赋值了,字符串就不能修改了:在go中字符串是不可变的
	//var str = "hello"
	//str[0] = "a" 这里就不能去修改str的内容,即go中的字符串是不可变的
	var str1 = `var address string 
	= "北京长城 110 hello world!"`  //反引号
	fmt.Println(str1)



}
// 执行结果
// 北京长城 110 hello world!
// var address string 
//         = "北京长城 110 hello world!"

4)字符串的拼接

5)当一行字符串太长时,需要使用到多行字符串,可以如下处理

示例

package main

import (
	"fmt"
)

func main(){
	var address string = "北京长城 110 hello world!"
	fmt.Println(address)
	//字符串一旦赋值了,字符串就不能修改了:在go中字符串是不可变的
	//var str = "hello"
	//str[0] = "a" 这里就不能去修改str的内容,即go中的字符串是不可变的
	var str1 = `var address string 
	= "北京长城 110 hello world!"`  //反引号
	fmt.Println(str1)
	var str2 string
	str2 = "hello" + "world"
	str3 := "chen" + "xi"
	str3 += "haha"
	fmt.Println(str3)
	//当一个拼接操作很长时,可以分行写;需要将+保留上一行
	str2 = "hello" + "world" +
	"hello" + "world"
	fmt.Println(str2)
}
// 执行结果
// 北京长城 110 hello world!
// var address string 
//         = "北京长城 110 hello world!"
// chenxihaha
// helloworldhelloworld

  基本数据类型默认值

image

 介绍

在go 中,数据类型都有一个默认值,当程序员没有赋值时,就会保留默认值,在go中,默认值又叫零值

package main

import (
	"fmt"
)

 func main(){

	var a int //0
	var b float32 //0
	var c float64 //0
	var isMarr bool //false
 	var name string //""
	//%v表示按照变量的值输出
	fmt.Printf("a=%d,b=%v,c=%v,isMarr=%v ,name=%v",a,b,c,isMarr,name)

}
// 执行结果
// a=0,b=0,c=0,isMarr=false ,name=

  基本数据的转换

介绍

golang 和java/C不同。go在不同类型的变量之间赋值时需要显式转换。也就是说golang中数据类型不能自动转换

基本语法

表示T(v)将值v转换为类型T

T: 表示数据类型,例如int32,int64,float32等等

v:就是需要转换的变量

 示例1

package main

import (
	"fmt"
)

 func main(){
	var t int = 45
	//将t =>float32
	var ti float32 = float32(t)

	fmt.Printf("i=%v n1=%v\n",t,ti)
	var r int8 = int8(t)
	fmt.Printf("r=%v ",r)

}
// 执行结果
/* i=45 n1=45
r=45  */

  细节

1)go 中数据类型转换可以是从小范围---》大范围,也可以大范围---》小范围

2)被转换的是变量存储的数据(即值),变量本身的数据类型没有变化

3)在转换中,比如int64转成int8。编译时不会报错,只是转换的结果是按溢出处理,和我们希望结果不一样

package main

import (
	"fmt"
)

 func main(){
	var t int = 45
	//将t =>float32
	var ti float32 = float32(t)

	fmt.Printf("i=%v n1=%v\n",t,ti)
	var r int8 = int8(t)
	fmt.Printf("r=%v \n",r)
	var num1 int64 = 999999
	var num2 int8 = int8(num1)
	fmt.Println("num2=",num2)

}
// 执行结果
// i=45 n1=45
// r=45  
// num2= 63

  如果没有使用一个包,不向去掉,前面加_ 

基本数据类型与string 类型

介绍

在开发中,我们经常需要将基本数据类型转成string类型。或者将string转成基本数据类型

基本数据类型转string类型

方式1:fmt.Sprintf("%参数",表达式)

1)参数需要和表达式的数据类型相匹配

2)fmt.Sprintf()..会返回转换后的字符串

func Sprintf(format string, a ...interface{}) string

Sprintf根据format参数生成格式化的字符串并返回该字符串。

示例

package main

import (
	"fmt"
)

 func main(){
	var a1 int = 76
	var a2 float64 = 3.14
	var a3 bool = true
	var a4 byte = 'h'
	var str string
	//使用第一种方式
	str = fmt.Sprintf("%d",a1)
	fmt.Printf("str type %T str=%v\n",str,str)
	str = fmt.Sprintf("%f",a2)
	fmt.Printf("str type %T str=%v\n",str,str)
	str = fmt.Sprintf("%t",a3)
	fmt.Printf("str type %T str=%v\n",str,str)
	str = fmt.Sprintf("%q",a4)//%q
	fmt.Printf("str type %T str=%v\n",str,str)
}
// 执行结果
// str type string str=76
// str type string str=3.140000
// str type string str=true
// str type string str='h'

  格式化输出注解 https://studygolang.com/pkgdoc

%v	值的默认格式表示
%+v	类似%v,但输出结构体时会添加字段名
%#v	值的Go语法表示
%T	值的类型的Go语法表示
%%	百分号
布尔值:

%t	单词true或false
整数:

%b	表示为二进制
%c	该值对应的unicode码值
%d	表示为十进制
%o	表示为八进制
%q	该值对应的单引号括起来的go语法字符字面值,必要时会采用安全的转义表示
%x	表示为十六进制,使用a-f
%X	表示为十六进制,使用A-F
%U	表示为Unicode格式:U+1234,等价于"U+%04X"
浮点数与复数的两个组分:

%b	无小数部分、二进制指数的科学计数法,如-123456p-78;参见strconv.FormatFloat
%e	科学计数法,如-1234.456e+78
%E	科学计数法,如-1234.456E+78
%f	有小数部分但无指数部分,如123.456
%F	等价于%f
%g	根据实际情况采用%e或%f格式(以获得更简洁、准确的输出)
%G	根据实际情况采用%E或%F格式(以获得更简洁、准确的输出)
字符串和[]byte:

%s	直接输出字符串或者[]byte
%q	该值对应的双引号括起来的go语法字符串字面值,必要时会采用安全的转义表示
%x	每个字节用两字符十六进制数表示(使用a-f)
%X	每个字节用两字符十六进制数表示(使用A-F)    
指针:

%p	表示为十六进制,并加上前导的0x    
没有%u。整数如果是无符号类型自然输出也是无符号的。类似的,也没有必要指定操作数的尺寸(int8,int64)。

宽度通过一个紧跟在百分号后面的十进制数指定,如果未指定宽度,则表示值时除必需之外不作填充。精度通过(可选的)宽度后跟点号后跟的十进制数指定。如果未指定精度,会使用默认精度;如果点号后没有跟数字,表示精度为0。举例如下:

%f:    默认宽度,默认精度
%9f    宽度9,默认精度
%.2f   默认宽度,精度2
%9.2f  宽度9,精度2
%9.f   宽度9,精度0    

  

方式2: 使用strconv包的函数;strconv包实现了基本数据类型和其字符串表示的相互转换。

func FormatBool

func FormatBool(b bool) string

根据b的值返回"true"或"false"。

 

func FormatInt

func FormatInt(i int64, base int) string

返回i的base进制的字符串表示。base 必须在2到36之间,结果中会使用小写字母'a'到'z'表示大于10的数字。

func FormatUint

func FormatUint(i uint64, base int) string

是FormatInt的无符号整数版本。

func FormatFloat

func FormatFloat(f float64, fmt byte, prec, bitSize int) string

示例
package main

import (
	"fmt"
	"strconv"
)

 func main(){
	var a1 int = 76
	var a2 float64 = 3.14
	var a3 bool = true
	var a4 byte = 'h'
	var str string
	//使用第一种方式
	str = fmt.Sprintf("%d",a1)
	fmt.Printf("str type %T str=%q\n",str,str)
	str = fmt.Sprintf("%f",a2)
	fmt.Printf("str type %T str=%q\n",str,str)
	str = fmt.Sprintf("%t",a3)
	fmt.Printf("str type %T str=%v\n",str,str)
	str = fmt.Sprintf("%q",a4)//%q
	fmt.Printf("str type %T str=%v\n",str,str)
	//使用第二种方式
	var a5 int = 76
	var a6 float64 = 3.14
	var a7 bool = true
	var s1 string
	s1 = strconv.FormatInt(int64(a5),10)
	fmt.Printf("s1 type %T s1=%q\n",s1,s1)
	//注解:'f' 格式 10: 表示小数位保留10位,64:表示这个小数是float64位
	s1 = strconv.FormatFloat(a6,'f',10,64)
	fmt.Printf("s1 type %T s1=%q\n",s1,s1)
	s1 = strconv.FormatBool(a7)
	fmt.Printf("s1 type %T s1=%q\n",s1,s1)
	s1 = strconv.Itoa(a5)
	fmt.Printf("s1 type %T s1=%q\n",s1,s1)
}
// 执行结果
// str type string str=76
// str type string str=3.140000
// str type string str=true
// str type string str='h'
// s1 type string s1="76"
// s1 type string s1="3.1400000000"
// s1 type string s1="true"
// s1 type string s1="76"

string 类型转为基本数据类型

使用strconv 包的函数;可以直接转换32位

package main

import (
	"fmt"
	"strconv"
)

 func main(){
	var str string = "true"
	var w1 bool
	//说明
	// strconv.ParseBool 会返回2个值,用一个接收是不行的,所以使用'_'空接收不要的值
	w1,_ = strconv.ParseBool(str)
	fmt.Printf("b type %T b 的值%v\n",w1,w1)
	var str2 string = "1234590"
	var w2 int64
	w2,_ = strconv.ParseInt(str2,10,64)
	fmt.Printf("w2 type %T w2=%v\n",w2,w2)
	var str3 string = "3.14256"
	var w3 float64
	w3,_ = strconv.ParseFloat(str3,64)
	fmt.Printf("w3 type %T w3=%v\n",w3,w3)


}
// 执行结果
// b type bool b 的值true
// w2 type int64 w2=1234590
// w3 type float64 w3=3.14256

    基本数据类型和string的类型转换

在将string 类型转为基本数据类型时,要确保string类型能够转成有效的数据,例如可以把‘123’,转成一个整数,但是不可以把hello 转成一个整数,如果这样,golang直接将其转成0;没有转成功不管以前是多少都成默认值

 示例

package main

import (
	"fmt"
	"strconv"
)

 func main(){
	var str4 string = "hello"
	var n3 int64 
	n3,_=strconv.ParseInt(str4,10,64)
	fmt.Printf("n2 type %T n2=%v\n",n3,n3)

}
// 执行结果
// n2 type int64 n2=0

 指针

基础介绍

1)基本数据类型,变量存的就是值,也叫值类型

2)获取变量的地址,用&,比如:var num int ,获取num的地址: &num

image

 

 

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

image

 

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

5)举例说明:

var num int = 1

var i = 999

var ptr *int = &i

 示例

package main

import (
	"fmt"
	_"strconv"
)

 func main(){
	//指针
	var i int =10
	//i的地址是什么,&i
	var prt *int = &i
	fmt.Println(prt)
	//打印地址值变量的变量地址
	fmt.Println(&prt)
	//根据指针的变量打印指向的值
	fmt.Println(*prt)
}
// 执行结果
// 0xc000112068
// 0xc000114020
// 10

  通过指针修改变量值

package main

import (
	"fmt"
	_"strconv"
)

 func main(){
	//指针
	var i int =10
	//i的地址是什么,&i
	var prt *int = &i
	fmt.Println(prt)
	//打印地址值变量的变量地址
	fmt.Println(&prt)
	//根据指针的变量打印指向的值
	fmt.Println("i =",i)
	*prt = 90
	fmt.Println("*prt=",*prt)
	fmt.Println("i=",i)

}
// 执行结果

// 0xc00000a0a8
// 0xc000058028
// i = 10
// *prt= 90
// i= 90

  指针细节说明

1)值类型,都有对应的指针类型,形式为*数据类型,比如int的对应的指针*int,float32,一次类推

2)值类型包括:基本数据类型int系列,float系列,bool,string,数组和结构体struct

值类型和引用类型

1)值类型:基本数据类型int系列,float系列,bool,string ,数组和结构体struct

2) 引用类型:指针、slice切片、map、管道chan、interface 等都是引用类型

值类型与引用类型使用特点

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

 

image

 

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

image

 

3)内存的栈区和堆区的示意图

image

 标识符的命名规范

1)golang 对各种变量、方法等命名时使用的字符序列称为标识符

2)凡是自己可以起名的地方都叫标识符

标识符命名规则

1)由26个英文字母大小写,0-9,_组成

2)数字不可以开头

3)golang严格区分大小写

var num int

var Num int

说明: 在golang 中,num和Num是两个不同的变量

package main

import (
	"fmt"
	_"strconv"
)

 func main(){
	//golang 中严格区分大小写
	var num int = 20
	var Num int = 45
	fmt.Printf("num=%v Num=%v\n",num,Num)

}
// 执行结果

// num=20 Num=45

  

4)标识符不能包含空格

下划线"_"本身在Go中是一个特殊的标识符,称为空标识符。可以代表任何其他的标志符,但是它对应的值会被忽略(比如:忽略某个返回值)。所以仅能被作为占位符,不能作为标识符。不能以系统保留关键字作为标识符

5)下划线"_"本身在Go中是一个特殊的标识符,称为空标识符。可以代表任何其他的标识符,但是它对应的值会被忽略(比如:忽略某个返回值)。所以,仅能被作为占用符使用,不能作为标识符使用

6)不能以系统保留关键字作为标识符,比如break,if等

标识符命名规范与注意事项

1)包名:保持package的名字和目标保持一致,尽量采取有意义的包名,简短有意义不要和标准库冲突、

2)变量名、函数名、常量名: 驼峰法

3)如果变量名、函数名、常量名、常量首字母大写,则可以被其的包访问,;如果首字母小写。则只能在本包使用(注:可以简单的理解成,首字母大写是公有的,首字母小写是私有的)

 示例

package model
//定义变量
var HeroName string = "松江"



package main

import (
	"fmt"
	"demo14/model"
	_ "strconv"

	//
	// 引入包
	//"chapter03/demo14/model"
)

 func main(){
	//golang 中严格区分大小写
	var num int = 20
	var Num int = 45
	fmt.Printf("num=%v Num=%v\n",num,Num)
    fmt.Println(model.HeroName)

}
// 执行结果
// D:\golang\goproject\src\src01\go_code\src\chapter03\demo14>go mod tidy

// D:\golang\goproject\src\src01\go_code\src\chapter03\demo14>go run ./main
// num=20 Num=45
// 松江

  系统保留关键字25个;在Go中,为了简化代码编译过程中对代码的解析,其定义的保留关键字只有25个

break      default      func         interface    select
case       defer        go           map          struct
chan       else         goto         package      switch
const      fallthrough  if           range        type
continue   for          import       return       var

  36个预定义标识符

基础类型17个

bool     byte    complex64  complex128  error  float32   float64  int
int8  int16  int32  int64  rune  string  uint  uint8  uint16  uint32  uint64  uintptr

  常量3个

true  false  iota

  零标识符 1

nil

  内建函数(15 个)

append  cap  close  complex  copy
delete  imag  len  make  new
panic  print  println  real  recover

  

 

posted @ 2025-12-11 15:07  烟雨楼台,行云流水  阅读(17)  评论(0)    收藏  举报