当前位置: 首页 > news >正文

Golang-02Golang变量与基本数据类型

Go语言文件的基本结构

package main  //声明属于什么包

//导入语句
import "fmt"

//函数外面只能声明标识符(变量、常量、函数、类型)

//程序的入口函数
func main() {
	fmt.Println("Hello world!")
}

创建实验目录

在这里插入图片描述

PS C:\Users\kaikai\Desktop\golang\001> go mod init 001  #001就是项目,一个项目只允许有一个入口,以后会经常使用
go: creating new go.mod: module 001
go: to add module requirements and sums:
        go mod tidy
PS C:\Users\kaikai\Desktop\golang\001> go mod tidy

在这里插入图片描述

变量和常量

声明变量

格式:var name 类型

//声明变量  注释使用//注释内容 或者是/* 注释内容 */  
var name string
var age int
var isOk bool

//批量声明
var (
	name string
	age  int
	isOk bool
)

Go语言中的变量必须先声明再使用,但是全局变量没有这个限制,在函数内部定义的变量不使用会造成编译不通过

package main

//1.这里不会造成编译不通过
var data int

func main() {
	//2.这里定义不使用编译不通过
	var data int
}

声明变量推荐使用骆驼命名法方法

变量赋值

声明变量同时赋值(不推荐)

var s1 string = "kaikai"
fmt.Print(s1)


----输出结果----
kaikai

类型推导

根据值判断这个变量是什么类型

var s2 = "20"
fmt.Print(s2)

----输出结果----
20

短变量声明

只能在函数内部使用,可以使用更简略的:=方式声明并初始化变量

s3 := "凯凯王"
fmt.Println(s3)

----输出结果----
凯凯王

匿名变量

在使用多重赋值时,如果想要忽略某一个值,可以使用匿名变量(anonymous variable)。匿名变量用一个下划线_

存在的意义,处理声明不使用的变量,表示忽略某一个值

package main

import "fmt"

func foo() (int, string) {
	return 10, "kaikai"
}

func main() {
	x, _ := foo()
	_, y := foo()
	fmt.Println("x=", x)
	fmt.Println("y=", y)
}

----输出结果----
x= 10
y= kaikai

在同一个作用域不能重复声明两个名字一样的变量

常量

相对于变量,常量是恒定不变的量

定义了常量是不能修改的,在运行期间不能修改

命名常量

const  pi = 3.141592654
const kaikai = "你说呢"

批量命名常量

const (
	statusOk = 200
	notFound = 404
)

//批量声明常量,如果一行声明没有赋值,默认就和上一行是一致
package main

import "fmt"
const (
	n1 = 100
	n2
	n3
)

func main() {

	fmt.Println(n1, n2, n3)
}

----输出结果----
100 100 100

iota

iota是go语言的常量计算器,只能在常量的表达式中使用

iota在const关键字出现时将重置为0,const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)

const (
	a1 = iota  //0
	a2         //1
	a3         //2
)

几个常见的iota示例:

使用_跳过某些值

const (
	c1 = iota //0
	c2 = iota //1
	_  = iota //2
	c3 = iota //3
)

iota声明中间插队

const (
	d1 = iota //0
	d2 = 100  //100
	d3 = iota //2
	d4        //3
)

多个变量在同一行

const (
	e1, e2 = iota + 1, iota + 2  //e1=1,e2=2
    e3, e4 = iota + 1, iota + 2  //e3=2,e4=3s
)

定义数量级

package main

import "fmt"

const (
	_  = iota
	KB = 1 << (10 * iota)
	MB = 1 << (10 * iota)
	GB = 1 << (10 * iota)
	TB = 1 << (10 * iota)
	PB = 1 << (10 * iota)
)

func main() {

	fmt.Println(KB, MB, GB, TB, PB)

}

----输出结果----
1024 1048576 1073741824 1099511627776 1125899906842624

fmt函数的使用

  • fmt.Print:在终端中输出要打印的内容
  • fmt.Println:%s占位符 使用name 这个变量的值去替换占位符
  • fmt.Printf:打印完指定的内容之后会在后面加一个换行符

在Go语言中间无格式的限制,也可以使用go fmt 程序代码 来格式代码

  • fmt.Println() 快速打印一个空行

fmt 包的格式化功能,你可以参考这里去看上面的代码

%b    表示为二进制
%c    该值对应的unicode码值
%d    表示为十进制
%o    表示为八进制
%q    该值对应的单引号括起来的go语法字符字面值,必要时会采用安全的转义表示
%x    表示为十六进制,使用a-f
%X    表示为十六进制,使用A-F
%v    查看值
%#v   加上描述符
%s    字符串类型
%U    表示为Unicode格式:U+1234,等价于"U+%04X"
%E    用科学计数法表示
%f    用浮点数表示
%T    查看类型

注释

行注释

基本语法: // 注释内容

在每一行的前面加上两个斜杆就可以注释这一行了。

ctrl + / 就会把你选中的多行代码全都注释。

块注释

基本语法:/*

注释内容

*/
这就相当于python里的“”“ 多行注释内容 ”“”

注:块注释里面不能有块注释,也就是说不能有嵌套

Go语言基本数据类型

整型

  • 有符号整型:int8、int16、int32、int64、int;
  • 无符号整型:uint8、uint16、uint32、uint64、uint。
类型字节数取值范围说明
int81-128~127有符号8位整型
uint810~255无符号8位整型
int162-32768~32767有符号16位整型
uint1620~65535无符号16位整型
int324-2147483648~2147483647有符号32位整型
uint3240~4294967295无符号32位整型
int648-9223372036854775808~9223372036854775807有符号64位整型
uint6480~18446744073709551615无符号64位整型

声明方式如下所示:

var a int8  // 声明有符号 8 位整型
var b uint8 // 声明无符号 8 位整型

特殊整型

类型字节数取值范围说明
int4或8取决于平台有符号32或64位整型
uint4或8取决于平台无符号32或64位整型
uintptr4或8取决于平台用于存放一个指针

不同进制数

不同进制的表示方法

出于习惯,在初始化数据类型为整型的变量时,我们会使用10进制的表示法,因为它最直观,比如这样,表示整数10.

var num int = 10

不过,你要清楚,你一样可以使用其他进制来表示一个整数,这里以比较常用的2进制、8进制和16进制举例。

2进制:以0b0B为前缀

var num01 int = 0b1100

8进制:以0o或者 0O为前缀

var num02 int = 0o14

16进制:以0x 为前缀

var num03 int = 0xC

下面用一段代码分别使用二进制、8进制、16进制来表示 10 进制的数值:12

package main

import (
	"fmt"
)

func main() {
    //十进制
	var i1 = 111
	fmt.Printf("%d\n", i1) // 十进制
	fmt.Printf("%b\n", i1) // 十进制转换为二进制
	fmt.Printf("%o\n", i1) // 十进制转换为八进制
	fmt.Printf("%x\n", i1) // 十进制转换为十六进制
    
    //八进制
	i2 := 077
	fmt.Printf("%d\n", i2)

	//十六进制
	i3 := 0x12345
	fmt.Printf("%d\n", i3)
    //使用%T查看变量的类型
    fmt.Printf("%T\n", i3)
    
	var num01 int = 0b1100
	var num02 int = 0o14
	var num03 int = 0xC
    
	fmt.Printf("2进制数 %b 表示的是: %d \n", num01, num01)
	fmt.Printf("8进制数 %o 表示的是: %d \n", num02, num02)
	fmt.Printf("16进制数 %X 表示的是: %d \n", num03, num03)
}

----输出结果----
111
1101111
157
6f
63
74565
int
2进制数 1100 表示的是: 12
8进制数 14 表示的是: 12
16进制数 C 表示的是: 12

浮点型

浮点数类型的值一般由整数部分、小数点“.”和小数部分组成。

其中,整数部分和小数部分均由10进制表示法表示。不过还有另一种表示方法。那就是在其中加入指数部分。指数部分由“E”或“e”以及一个带正负号的10进制数组成。比如,3.7E-2表示浮点数0.037。又比如,3.7E+1表示浮点数37

有时候,浮点数类型值的表示也可以被简化。比如,37.0可以被简化为37。又比如,0.037可以被简化为.037

有一点需要注意,在Go语言里,浮点数的相关部分只能由10进制表示法表示,而不能由8进制表示法或16进制表示法表示。比如,03.7表示的一定是浮点数3.7

float32 和 float64

Go语言中提供了两种精度的浮点数 float32 和 float64。

float32,也即我们常说的单精度,存储占用4个字节,也即4*8=32位,其中1位用来符号,8位用来指数,剩下的23位表示尾数

float64,也即我们熟悉的双精度,存储占用8个字节,也即8*8=64位,其中1位用来符号,11位用来指数,剩下的52位表示尾数 (go中间小数默认就是float64)

  • 常量 math.MaxFloat32 表示 float32 能取到的最大数值,大约是 3.4e38;
  • 常量 math.MaxFloat64 表示 float64 能取到的最大数值,大约是 1.8e308;
  • float32 和 float64 能表示的最小值分别为 1.4e-45 和 4.9e-324。

布尔值

  • 使用bool声明,只有true和false

  • 默认是false

  • 不允许将整型强制转换为布尔值

  • 布尔值无法参与数值运算,也无法于其他类型进行转换

字符串

  • 内部使用的是UTF-8编码
  • 包裹字符串的符号为(“”)双引号,单引号包裹的是字符
package main

import (
	"fmt"
)

func main() {
	//字符串
	s := "hello kaikai"
	//单独的字母、汉字、符合表示一个字符
	c1 := 'h'
	c2 := '1'
	c3 := "凯"
	//字节:1字节=8Bit(8个二进制位)
	//1个字符'A'=1个字节
	//1个utf8编码的汉字一般占3个字节
	fmt.Printf(s, c1, c2, c3)
}

----输出结果----
hello kaikai%!(EXTRA int32=104, int32=49, string=)

字符串转义符

\r:回车符(返回行首)
\t: 表示一个制表符,通常使用它可以排版。
\n :换行符(直接跳到下一行的同列位置)
\' :单引号
\" :双引号
\\ : 反斜杠

字符串赋值

单行赋值

s1 := "我是一个好人"

多行赋值

s2 := `
人生路
天天学
学不完
够用就行
`

字符串的常用操作

方法介绍
len(str)求长度
+或fmt.Sprintf拼接字符串
strings.Split分割
strings.contains判断是否包含
strings.HasPrefix,strings.HasSuffix前缀/后缀判断
strings.Index(),strings.LastIndex()子串出现的位置
strings.Join(a[]string, sep string)join操作

byte和rune类型

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

  1. uint8类型,或者叫 byte 型,代表了ASCII码的一个字符。
  2. rune类型,代表一个 UTF-8字符

当需要处理中文、日文或者其他复合字符时,则需要用到rune类型。rune类型实际是一个int32

因为UTF8编码下一个中文汉字由3~4个字节组成,所以我们不能简单的按照字节去遍历一个包含中文的字符串,否则就会出现上面输出中第一行的结果。

字符串底层是一个byte数组,所以可以和[]byte类型相互转换。字符串是不能修改的 字符串是由byte字节组成,所以字符串的长度是byte字节的长度。 rune类型用来表示utf8字符,一个rune字符由一个或多个byte组成。

修改字符串

要修改字符串,需要先将其转换成[]rune[]byte,完成后再转换为string。无论哪种转换,都会重新分配内存,并复制字节数组。

package main

import (
	"fmt"
)

func main() {
	s1 := "big"
	// 强制类型转换
	byteS1 := []byte(s1)
	byteS1[0] = 'p'
	fmt.Println(string(byteS1))

	s2 := "白萝卜"
	runeS2 := []rune(s2) //把字符串强制转换成一个rune切片
	runeS2[0] = '红'
	fmt.Println(string(runeS2))
}

----输出结果----
pig
红萝卜

类型转换

go 存在常见的类型转换分别为:断言、强制。

package main

import "fmt"

func main() {
    var a float32 = 5.6
    var b int = 10
    fmt.Println (a * b)
}

这样的代码会报错,因为类型不匹配
这时候需要强制类型转换

转换格式 表达式 T(v)

package main

import "fmt"

func main() {
    var a float32 = 5.6
    var b int = 10
    fmt.Println (a * float32(b))
}

这样就不会报错了

func main() {
	var a int32 = 1999999      // 小转大一样要显示转换
	var b float64 = float64(a) // a转b  a本身数据类型并不会改变,只是把a的值的值转成了float64
	var c int8 = int8(a)       // 大转小不会报错,但是数据溢出会丢失数据
	fmt.Println(c)
	fmt.Printf("%T,%T,%T", a, b, c)
}

----运行结果----
127
int32,float64,int8

普通变量类型int,float,string 都可以使用 type (a)这种形式来进行强制类型转换,比如

var a int32  = 10
var b int64 = int64(a)
var c float32 = 12.3
var d float64 =float64(c)

指针也是有类型的

基本类型转string

func main() {
	var (
		num1 int     = 9
		num2 float64 = 9.99
		b    bool    = false
		c    byte    = 'a'
		str  string
	)

	str = fmt.Sprintf("%d", num1)
	fmt.Printf("str的类型: %T\t 值:%v\n ", str, str)

	str = fmt.Sprintf("%f", num2)
	fmt.Printf("str的类型: %T\t 值:%v\n ", str, str)

	str = fmt.Sprintf("%t", b)
	fmt.Printf("str的类型: %T\t 值:%v\n ", str, str)

	str = fmt.Sprintf("%c", c)
	fmt.Printf("str的类型: %T\t 值:%v\n ", str, str)
}

----运行结果----
str的类型: string      值:9
str的类型: string      值:9.990000
str的类型: string      值:false
str的类型: string      值:a

数字转字符串类型

strconv.Itoa 可以将数字转换成字符串类型的数字

func main() {
	var (
		num  int     = 24
		num2 float64 = 1.111
		str  string
	)

	// FormatInt参数1:要转的变量  参数2:进制
	str = strconv.FormatInt(int64(num), 10)
	fmt.Printf("str的类型: %T\t 值:%v\n ", str, str)

	// strconv.FormatInt也可以用来转换进制,比如将10进制转换为2进制,其它进制,换掉后面的数字就可以了
	str = strconv.FormatInt(123, 2)
	fmt.Printf("str的类型: %T\t 值:%v\n ", str, str)

	// 'f':格式  10:保留10位   64:float64
	str = strconv.FormatFloat(num2, 'f', 10, 64)
	fmt.Printf("str的类型: %T\t 值:%v\n ", str, str)

	str = strconv.FormatBool(false)
	fmt.Printf("str的类型: %T\t 值:%v\n ", str, str)

	str = strconv.Itoa(num) //
	fmt.Printf("str的类型: %T\t 值:%v\n ", str, str)
}

----运行结果----
str的类型: string      值:24
str的类型: string      值:1111011
str的类型: string      值:1.1110000000
str的类型: string      值:false
str的类型: string      值:24

指针的强制类型

指针的强制类型转换需要用到unsafe包中的函数实现

package main

import "unsafe"
import "fmt"

func main() {
    var a int =10
    var b *int =&a
    var c *int64 = (*int64)(unsafe.Pointer(b))
    fmt.Println(*c)
}

string转基本类型

func main() {
	var (
		str string = "123"
		i   int64  // 这里只能用int64
		f   float64
		b   bool
	)
	// str:字符串	base:进制	bitSize:int64
	i, _ = strconv.ParseInt(str, 10, 64)
	fmt.Printf("i的类型: %T\t 值:%v\n ", i, i)

	f, _ = strconv.ParseFloat(str, 64)
	fmt.Printf("f的类型: %T\t 值:%v\n ", f, f)

	b, _ = strconv.ParseBool(str)
	fmt.Printf("b的类型: %T\t 值:%v\n ", b, b)

	s, _ := strconv.Atoi("str")
	fmt.Printf("s的类型: %T\t 值:%v\n ", s, s)
}

----运行结果----
i的类型: int64     值:123
f的类型: float64   值:123
b的类型: bool      值:false
s的类型: int       值:0

字符串转字节切片

func main() {
  // 字符串转切片
	var b = []byte("itzhuzhu")
	fmt.Printf("b=%v\n", b)

  // 切片转字符串
	var str = string([]byte{97, 98, 99})
	fmt.Printf("str=%v\n", str)
}

----运行结果----
b=[105 116 122 104 117 122 104 117]
str=abc

类型断言

package main

import "fmt"

func main() {
    var x interface{} =10
    switch i := x.(type) {
case nil:
    printString("x is nil")                // type of i is type of x (interface{})
case int:
    printInt(i)                            // type of i is int
case float64:
    printFloat64(i)                        // type of i is float64
case func(int) float64:
    printFunction(i)                       // type of i is func(int) float64
case bool, string:
    printString("type is bool or string")  // type of i is type of x (interface{})
default:
    printString("don't know the type")     // type of i is type of x (interface{})
}
}

还有一种t,ok:= x.(int)有两个返回值,第一个是对应类型的值,第二个是bool类型的,类型判断是否正确。

相关文章:

  • 在线五子棋对战 --- 人机对战的实现
  • 【微信小程序】shrio安全登录界面实现
  • Apache网页的优化,安全与防盗链
  • python中Try的运用及意义
  • React中实现插槽效果的方案
  • 一起Talk Android吧(第三百八十九回:介绍两种实现倒计时的方法)
  • SystemVerilog——线程以及线程之间的通信
  • Node.js 应用开发详解开篇词 Node.j 从工程化工具到后端服务应用的转变
  • 【Android】Android Binder进程间通信AIDL示例与源码分析
  • ARM学习(12)基于arm架构的嵌入式操作系统理解
  • pytorch利用hook【钩子】获取torch网络每层结构【附代码】
  • 快速了解Nginx的基本介绍
  • 字符串统计:strlen函数的讲解,及其模拟实现
  • Linux——什么是环境变量?
  • 关于软件定时器的一些讨论
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • Android组件 - 收藏集 - 掘金
  • AngularJS指令开发(1)——参数详解
  • Hibernate【inverse和cascade属性】知识要点
  • Javascript弹出层-初探
  • jQuery(一)
  • js ES6 求数组的交集,并集,还有差集
  • js继承的实现方法
  • JS题目及答案整理
  • js中forEach回调同异步问题
  • Redash本地开发环境搭建
  • 从零搭建Koa2 Server
  • 对JS继承的一点思考
  • 简单实现一个textarea自适应高度
  • 使用putty远程连接linux
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 小程序button引导用户授权
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • 原生JS动态加载JS、CSS文件及代码脚本
  • 运行时添加log4j2的appender
  • ​批处理文件中的errorlevel用法
  • $ git push -u origin master 推送到远程库出错
  • (23)Linux的软硬连接
  • (day6) 319. 灯泡开关
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (Ruby)Ubuntu12.04安装Rails环境
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (十) 初识 Docker file
  • (四)linux文件内容查看
  • (未解决)macOS matplotlib 中文是方框
  • (循环依赖问题)学习spring的第九天
  • (转)Linux整合apache和tomcat构建Web服务器
  • (状压dp)uva 10817 Headmaster's Headache
  • .Net CoreRabbitMQ消息存储可靠机制
  • .Net Remoting常用部署结构
  • .net 托管代码与非托管代码
  • .NET 中让 Task 支持带超时的异步等待
  • .NET6 命令行启动及发布单个Exe文件