【go从入门到精通】go基本类型和运算符用法

news2024/9/22 11:41:59

             大家好,这是我给大家准备的新的一期专栏,专门讲golang,从入门到精通各种框架和中间件,工具类库,希望对go有兴趣的同学可以订阅此专栏。

---------------------------------------------------------------------------------------------------------------------------------

             上一篇文章中 【go从入门到精通】go包,内置类型和初始化顺序  偏重概念和知识,想必大家都对如何开始写代码已经开始蠢蠢欲动了,但是不要着急,基础知识扎实,能让你少走很多弯道。

基本数据类型

        正如前一篇的内容,go的基本数据类型和其他语言都差不多,我们可以先看看go是如何声明变量的。

标准声明

Go语言的变量声明格式为:

    var 变量名 变量类型

变量声明以关键字var开头,变量类型放在变量的后面,行尾无需分号。 举个例子:

    var str string 
    var i   int32
    var b   bool 

批量声明

每声明一个变量就需要写var关键字会比较繁琐,go语言中还支持批量变量声明:

    var (
        a string
        b int
        c bool
        d float32
    )

变量的初始化

Go语言在声明变量的时候,会自动对变量对应的内存区域进行初始化操作。每个变量会被初始化成其类型的默认值,例如: 整型和浮点型变量的默认值为0。 字符串变量的默认值为空字符串。 布尔型变量默认为false。 切片、函数、指针变量的默认为nil

当然我们也可在声明变量的时候为其指定初始值。变量初始化的标准格式如下:

    var 变量名 类型 = 表达式

举个例子:

    var a int32 = 1 

 类型推导
有时候我们会将变量的类型省略,这个时候编译器会根据等号右边的值来推导变量的类型完成初始化。

    var str = "pprof.cn"
    var i = 1
短变量声明
在函数内部,可以使用更简略的 := 方式声明并初始化变量。

package main

import (
	"fmt"
)

func main() {
	var i = 10
	j := 100
	fmt.Println(i,j)
}


匿名变量
        在使用多重赋值时,如果想要忽略某个值,可以使用匿名变量。 匿名变量用一个下划线_表示,例如我希望通过strconv。Atoi来将数字字符串转整型数字,由于这个函数有2个返回值,我只想用i接收最终的整型变量,用_来作为匿名变量,可以用下面的代码来实现:

package main

import (
	"fmt"
	"strconv"
)

func main() { 
	i,_:=strconv.Atoi("100")
	fmt.Println(i)
}


            匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。 (在Lua等编程语言里,匿名变量也被叫做哑元变量。)

注意事项:

    函数外的每个语句都必须以关键字开始(var、const、func等)

    :=不能使用在函数外。

    _多用于占位,表示忽略值。

const常量的初始化


        相对于变量,常量是恒定不变的值,多用于定义程序运行期间不会改变的那些值。 常量的声明和变量声明非常类似,只是把var换成了const,常量在定义的时候必须赋值。

    const pi = 3.1415  

const同时声明多个常量时,如果省略了值则表示和上面一行的值相同。 例如:

    const (
        n1 = 100
        n2
        n3
    )
上面示例中,常量n1、n2、n3的值都是100。

其他注意的

但是这里要注意的一些区别是:

      (1) 空指针值 nil :

package main

import (
	"fmt"
) 
func main(){
	i := 0
	p := &i 
	if p == nil {
		fmt.Println("p is nil")
	} 
}

       (2)多行字符串的输出方式:

        Go语言中要定义一个多行字符串时,就必须使用反引号字符:

package main

import (
	"fmt"
) 
func main(){
	s := `this
		  is
		  golang
		  program`
		  
	fmt.Println(s)
}

反引号间换行将被作为字符串中的换行,但是所有的转义字符均无效,文本将会原样输出。

    

      (3)byte和rune类型

        组成每个字符串的元素叫做“字符”,可以通过遍历或者单个获取字符串元素获得字符。 字符用单引号(’)包裹起来,如:

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

    uint8类型,或者叫 byte 型,代表了ASCII码的一个字符。

    rune类型,代表一个 UTF-8字符。

    var a := '啊'
    var b := 'b'

当需要处理中文、日文或者其他复合字符时,则需要用到rune类型。rune类型实际是一个int32
Go 使用了特殊的 rune 类型来处理 Unicode,让基于 Unicode的文本处理更为方便,也可以使用 byte 型进行默认字符串处理,性能和扩展性都有照顾

package main

import (
	"fmt"
)

func disp() {
	s := "hello 你好"
	for i := 0; i < len(s); i++ { //byte
		fmt.Printf("%v(%c) ", s[i], s[i])
	}
	fmt.Println("")
	for _, r := range s { //rune
		fmt.Printf("%v(%c) ", r, r)
	}
}
func main() {
	disp()
}

输出:

104(h) 101(e) 108(l) 108(l) 111(o) 32( ) 228(ä) 189(½) 160( ) 229(å) 165(¥) 189(½) 
104(h) 101(e) 108(l) 108(l) 111(o) 32( ) 20320(你) 22909(好)

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

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

我们有时候会有这样的需求,判断某个游戏玩家起的昵称不能超过10个汉字或者字符,那么我想你这个时候就知道用哪种方式了。

 (4)修改字符串

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

package main
import (
	"fmt"
)

func modstring1(s string) {
	// 强制类型转换
	bytes := []byte(s)
	bytes[0] = 'H'
	fmt.Println(string(bytes))
}
func modstring2(s string) {
	// 强制类型转换
	bytes := []rune(s)
	bytes[0] = '你'
	fmt.Println(string(bytes))
}
func main() {
	s := "hello"
	modstring1(s)
	modstring2(s)
}

      (5)array数组    

            go的数组array是同一种数据类型的固定长度的序列。

           (1)如何定义一个数组呢?我们可以用: var 数组名   [长度],不过你要注意的是长度也是数组类型的一部分。
             比如:

                var a [10]int 和var a [100]int是不同的类型    

               var arr0 [5]int = [5]int{1, 2, 3}  // 未初始化元素值为 0。 

               c := [5]int{2: 100, 4: 200} // 使用索引号初始化元素。

               var arr2 = [...]int{1, 2, 3, 4, 5, 6}  // 通过初始化值确定数组长度。
          

            (2)数组可以通过下标进行访问,下标是从0开始,最后一个元素下标是:len-1

          遍历数组有两种方式:

    for i := 0; i < len(a); i++ {
    }
    for index, v := range a {
    }


             (3)访问越界,如果下标在数组合法范围之外,则触发访问越界,会panic

         

package main

import "fmt"

func main() {
	a := [3]int{1, 2, 3}
	b := a[0]
	c := a[6]
	fmt.Println(b, c)
}

 运行时报错信息如下:

PS E:\project\go\hello> ./main.exe
panic: runtime error: index out of range [6] with length 3

goroutine 1 [running]:
main.main()
        E:/project/go/hello/main.go:8 +0x1d

         
               (4) 数组是值类型,赋值和传参会复制整个数组,而不是指针。因此改变副本的值,不会改变本身的值。

       此时此刻,    一定有人想做下验证,于是写了如下代码:

package main

import "fmt"

func fun1(a []int) {
	a[0] = 100
}
func main() {
	a := []int{1, 2, 3}
	fun1(a)
	fmt.Println(a[0])
}

       这段代码似乎是想修改数组a的第一个元素的值,但是很不幸,你可能认为调用fun1之后,a的第一个元素的值仍然是1。

      为什么呢?  因为你传的不是数组,而且切片。 数组是指定了长度,且是值传递 而切片是没有指定长度,且是引用传递。所以你的代码改成这样就没有问题了:

package main

import "fmt"

func fun1(a [3]int) {
	a[0] = 100
}
func main() {
	a := [3]int{1, 2, 3}
	fun1(a)
	fmt.Println(a[0])
}

   (6)slice和map

       后边逐步针对这slIce,map,以及和数组的三者之间的比较差异来细细道来。 

类型转换


        Go语言中只有强制类型转换,没有隐式类型转换。该语法只能在两个类型之间支持相互转换的时候使用。

强制类型转换的基本语法如下:

        目标类型(表达式)
其中,目标类型表示要转换的类型。表达式包括变量、复杂算子和函数返回值等.

package main

import (
	"fmt"
)
 
func main() {
	i := int32(0)
	var j int
	j = i 
	fmt.Println(j) 
}
		

 比如这段代码,简简单单,但是编译的时候报错:

cannot use i (variable of type int32) as int value in assignment

所以我们在把i赋值给j的时候,需要做个类型强制转换,j = int(i)

运算符

         go的常用的运算符用法和其他语言没有区别

      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1487793.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

架构设计方法(4A架构)-应用架构

1、应用架构&#xff08;AA&#xff09;&#xff1a;业务价值与产品之间的桥梁&#xff0c;是企业架构的一个子集 2、应用架构包含“应用系统模块、应用服务、应用系统集成”3个关键要素 3、收集AS-IS应用架构&#xff0c;描绘现状&#xff0c;并识别改进机会点 4、描述对新系统…

xss.haozi:0x00

0x00没有什么过滤所以怎么写都没有关系有很多解 <script>alert(1)</script>

新书速览|Photoshop+CorelDRAW商业广告设计入门到精通:视频教学版

8章实例剖析商业案例&#xff0c;帮你提升设计效率。商业实战案例&#xff0c;真正掌握设计技能&#xff01; 本书内容 《PhotoshopCorelDRAW商业广告设计入门到精通&#xff1a;视频教学版》以创作精美、类型多样的案例&#xff0c;全面地讲解Photoshop与CorelDRAW软件相结合…

什么是五更泻及治疗方法

什么是五更泻 有些人总是在黎明之前肚脐周围的腹部疼痛发作&#xff0c;肚子咕咕作响&#xff0c;马上就想大便&#xff0c;拉出来的大便不成形&#xff0c;甚至有未消化的食物&#xff0c;便后会感觉舒服很多&#xff0c;还常伴有小腹冷痛、喜温、腰酸肢冷、舌淡苔白等症状。…

李沐动手学习深度学习——4.5练习

1. 在本节的估计问题中使用λ的值进行实验。绘制训练和测试精度关于λ的函数。观察到了什么&#xff1f; 修改代码运行如图所示&#xff0c;可以发现对于lamda值的变化而言&#xff0c;对于训练loss和测试loss的影响不大。但是如果λ 太大后&#xff0c;train和test的loss会变得…

欧拉回路(Eulerian Path)

1.定义 如果图 G G G(有向图或者无向图)中所有边一次仅且一次行遍所有顶点的通路称作欧拉通路。 如果图 G G G中所有边一次仅且一次行遍所有顶点的回路称作欧拉回路。 具有欧拉回路的图成为欧拉图(简称 E E E图)。具有欧拉通路但不具有欧拉回路的图成为半欧拉图。 顶点可以经…

【Docker】Windows11操作系统下安装、使用Docker保姆级教程

【Docker】Windows11操作系统下安装、使用Docker保姆级教程 大家好 我是寸铁&#x1f44a; 总结了一篇【Docker】Windows11操作系统下安装、使用Docker保姆级教程的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 前言 什么是 Docker&#xff1f; Docker 是一个开源平台&…

yolov8-更换卷积模块-ContextGuidedBlock_Down

源码解读 class ContextGuidedBlock_Down(nn.Module):"""the size of feature map divided 2, (H,W,C)---->(H/2, W/2, 2C)"""def __init__(self, nIn, dilation_rate2, reduction16):"""args:nIn: the channel of input fea…

统信UOS及麒麟KYLINOS操作系统上如何切换键盘布局

原文链接&#xff1a;如何切换键盘布局 | 统信UOS | 麒麟KYLINOS Hello&#xff0c;大家好啊&#xff0c;最近有朋友在群里提到他的键盘输入“Y”会显示“Z”&#xff0c;输入“Z”会显示“Y”。这个问题听起来可能有些奇怪&#xff0c;但其实并不罕见。出现这种情况的原因&…

广东Lenovo SR588服务器维修升级硬盘内存

本案例描述了对联想SR588服务器进行硬件升级的过程&#xff0c;包括更换固态硬盘作为系统盘&#xff0c;以及增加内存容量至128GB。升级后&#xff0c;服务器性能得到显著提升&#xff0c;同时通过重新配置RAID阵列和操作系统的重新安装&#xff0c;确保了系统的稳定性和数据的…

RAC集群日常维护

RAC的启停 cd /u01/app/19.3.0/grid/bin 停止 ./crsctl stop crs 检查 ./crsctl check crs 启动&#xff0c;可以两个节点同时启动 ./crsctl start crs 检查 ./crsctl check crs ./crsctl status res -t oracle的RAC日常维命令 集群状态检查命令 cractl status res …

数字革命的浪潮:Web3如何改变一切

随着数字技术的不断发展&#xff0c;人类社会正迎来一场前所未有的数字革命浪潮。在这个浪潮中&#xff0c;Web3技术以其去中心化、安全、透明的特性&#xff0c;正在逐渐改变着我们的生活方式、商业模式以及社会结构。本文将深入探讨Web3技术如何改变一切&#xff0c;以及其所…

基于springboot实现粮食仓库管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现粮食仓库管理系统演示 摘要 粮食作为人类生活的重要物质来源&#xff0c;在粮食流通过程中对于粮食仓库的管理不容忽视&#xff0c;随着我国粮食生产能力的提升以粮食存储管理的不断革新&#xff0c;粮食产量的增加为粮食仓储管理带来了挑战也带来了机遇&am…

JavaScript 中的类型转换机制(详细讲解)

文章目录 一、概述二、显示转换Number()parseInt()String()Boolean() 三、隐式转换自动转换为布尔值自动转换成字符串自动转换成数值 一、概述 前面我们讲到&#xff0c;JS中有六种简单数据类型&#xff1a;undefined、null、boolean、string、number、symbol&#xff0c;以及…

【BUUCTF Misc】通关1.0

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

网工学习 DHCP配置-接口模式

网工学习 DHCP配置-接口模式 学习DHCP总是看到&#xff0c;接口模式、全局模式、中继模式。理解起来也不困难&#xff0c;但是自己动手操作起来全是问号。跟着老师视频配置啥问题没有&#xff0c;自己组建网络环境配置就是不通&#xff0c;悲催。今天总结一下我学习接口模式的…

源码全开源可二次开发+求职招聘找工作小程序源码系统 带完整的搭建教程

随着移动互联网的普及和深入&#xff0c;小程序作为一种轻量级的应用形态&#xff0c;以其无需下载安装、即用即走的特点&#xff0c;迅速成为了连接线上线下的重要桥梁。特别是在求职招聘领域&#xff0c;小程序以其便捷性和高效性&#xff0c;成为了求职者与招聘方之间的理想…

wordpress 开源主题

海外就医wordpress主题 出国看病、海外就医是越来越多中产家庭的选择&#xff0c;此wordpress主题适合做相关业务的公司官网。 https://www.jianzhanpress.com/?p5220 防护wordpress外贸主题 个人防护器具wordpress外贸主题&#xff0c;适合做劳动保护的外贸公司使用。 ht…

【云原生】kubeadm快速搭建K8s集群Kubernetes1.19.0

目录 一、 Kubernetes 的概述 二、服务器配置 2.1 服务器部署规划 2.2服务器初始化配置 三、安装Docker/kubeadm/kubelet【所有节点】 3.1 安装Docker 3.2 添加阿里云YUM软件源 3.3 安装kubeadm&#xff0c;kubelet和kubectl 四、部署Kubernetes Master 五、部署Kube…

Javascript如何获取指定网页中的内容?

前言: 这两天有一个需求&#xff0c;即利用JavaScript语言来检索网页的文本内容。当然&#xff0c;实现这一目标的途径并非单一&#xff0c;除了我即将分享的特定技巧之外&#xff0c;还有另一种方法值得一提&#xff1a;通过Ajax的GET请求。然而&#xff0c;相比之下&#xff…