Go语言基础(一)

server/2024/10/23 21:11:11/

Go 是一门编译型语言,Go 语言的工具链将源代码及其依赖转换成计算机的机器指令(译注:静态编译)。Go 语言提供的工具都通过一个单独的命令 

go 调用,go 命令有一系列子命令。最简单的一个子命令就是 run。这个命令编译一个或多个以。.go 结尾的源文件,链接库文件,并运行最终生成的可执行文件。

  • 缺少了必要的包或者导入了不需要的包,程序都无法编译通过(与Java不同,golang中只要导入的包必须使用)
  • 循环只有for循环一种
  • 有i++,没有++i
  • 没有指针运算
  • 部署无依赖
  • 函数可返回多个值

数据类型

前2种为基本数据类型

1、布尔类型

布尔型的值只可以是常量 true 或者 false

2、数字类型

整型 int 和浮点型 float32、float64,Go 语言支持整型和浮点型数字,并且支持复数,其中位的运算采用补码。

整形

无符号:uint8(byte)、uint16(short)、uint32(int)、uint64(long)

有符号:int8(byte)、int16(short)、int32(int)、int64(long)

浮点型

float32(float)、float64(double)  float默认指float64

complex64:32位实数和虚数

complex128:64位实数和虚数

其它:byte类似uint8、rune类似int32、uint32或64 位、int与uint 一样大小、uintptr无符号整型用于存放一个指针

3、字符串类型

  • 字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本。
  • 在Go语言中,字符串类型是一个结构体,包含一个指向底层数据的指针和一个表示字符串长度的整数。在64位系统上,每个指向底层数据的指针占用8字节,表示字符串长度的整数占用8字节。因此,一个字符串类型在64位系统上总共占用16字节的空间。

go中实际没有字符类型,因为实际存储的是Unicode中的字符对应的编码值,是一个整形,如果直接将字符常量赋值给未指定类型的变量,Go编译器会将其视为 int32 类型(即 rune),但如果你将字符常量作为表达式的一部分(比如赋值给字符串或与其他字符串拼接),它会被隐式转换为字符串。

4、派生类型

  • (a) 指针类型(pointer)
  • (b) 数组类型
  • (c) 结构体类型(struct)
  • (d) 通道类型(channel)
  • (e) 函数类型
  • (f) 切片类型(slice)
  • (g) 接口类型(interface)
  • (h) Map类型

类型转换

go不支持隐式转换类型

普通类型

type_name(expression)
type_name 为类型,expression 为表达式package main
import "fmt"func main() {var sum int = 17var count int = 5var mean float32mean = float32(sum)/float32(count)fmt.Printf("mean 的值为: %f\n",mean)//mean 的值为: 3.400000
}

接口类型

接口类型转换分为:类型断言类型转换

类型断言:用于将接口类型转换为指定类型

value.(type) 
或者 
value.(T)
//其中 value 是接口类型的变量,type 或 T 是要转换成的类型(把前转成后)
//如果类型断言成功,它将返回转换后的值和一个布尔值,表示转换是否成功

类型转换:用于将一个接口类型的值转换为另一个接口类型

value.(type) 
或者 
value.(T)
//其中 value 是接口类型的变量,type 或 T 是要转换成的类型(把前转成后)
//如果类型断言成功,它将返回转换后的值和一个布尔值,表示转换是否成功

空接口类型:空接口interface{}可以持有任何类型的值,经常被用来处理多种类型的值

变量

变量名由字母、数字、下划线组成,其中首个字符不能为数字。

%T打印变量类型

变量声明

1、指定变量类型,如果没有初始化,则变量默认为零值。

       零值就是变量没有做初始化时系统默认设置的值。数值类型为0,布尔类型为false,字符串为""(空字符串),派生类型为nil

2、根据值自行判定变量类型。(指定值但不指定类型,则根据值自动推断类型 )

3、声明变量时var关键字 和 := 只能使用其一不能同时使用

  • 被var声明的变量不能再使用 :=声明
  •  := 声明只能在函数体内,不可以用于全局变量的声明与赋值,这种声明方式称之为初始化声明

注意

  • 在相同的代码块中(同一个中括号内),同一个变量只能初始化声明一次
  • 局部变量:代码块中声明的一个局部变量,必须在此代码块中被使用(不允许只声明但不使用)

        全局变量:允许只声明不使用

  • Go 语言程序中全局变量与局部变量名称可以相同,但是函数内的局部变量会被优先考虑

值类型和引用类型

值类型

整数类型、浮点数类型、布尔类型、字符类型(rune代表一个Unicode码点,是int32的别名,可以占1~4个字节)、数组结构体、字符串

(基本数据类型+派生类型中的数组和结构体)

这些类型的变量直接指向存在内存中的值,当使用等号 = 将一个变量的值赋值给另一个变量时,如:j = i,实际上是在内存中将 i 的值进行了拷贝

引用类型

指针、切片、映射、通道、接口(都是派生类型)

r1和r2为指针,当使用赋值语句 r2 = r1 时,只有引用(地址)被复制。如果 r1 的值被改变了,那么这个值的所有引用都会指向被修改后的内容,r2 也会受到影响。

特殊说明

  • 字符串:虽然字符串是序列化的,但它们是不可变的,所以每次修改字符串操作都会产生一个新的字符串。尽管如此,在概念上,字符串通常被认为是值类型。
  • 接口:接口是引用类型,因为它们存储的是指向实际数据的指针和类型信息。但是,当接口为空(即没有存储任何值)时,它本身不持有任何引用。

特殊

  • 如果你想要交换两个变量的值,则可以简单地使用 a, b = b, a,两个变量的类型必须是相同。
  • 空白标识符 _ 也被用于抛弃值,如值 5 在:_, b = 5, 7 中被抛弃。

_ 实际上是一个只写变量,你不能得到它的值。这样做是因为 Go 语言中你必须使用所有被声明的变量,但有时你并不需要使用从一个函数得到的所有返回值。

变量作用域

作用域为已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。

全局变量与局部变量名称可以相同,但是在函数内,局部变量会被优先考虑

Go 语言中变量可以在三个地方声明:

  • 函数内定义的变量称为局部变量

    局部变量的作用域只在函数体内,参数和返回值变量也是局部变量

  • 函数外定义的变量称为全局变量

    全局变量可以在整个包甚至外部包(被导出后)使用。

  • 函数定义中的变量称为形式参数(函数形参)

    形式参数会作为函数的局部变量来使用

常量

常量用const声明(替代var),表示在程序运行时,不会被修改的量

常量中的数据类型只可以是布尔型、数字型和字符串型,不能是派生类型

注意:常量可以用len(), cap(), unsafe.Sizeof()函数计算表达式的值。常量表达式中,函数必须是内置函数(go语言自带函数)

iota

特殊常量,是一个可以被编译器修改的常量

iota 在 const 关键字出现时将被重置为 0(const 内部的第一行之前),只要遇到一次const,iota就变为0

const 中每新增一行常量声明将使iota计数一次,新增一行常量声明后iota自动+1,iota 可理解为 const 语句块中的行索引

package mainimport "fmt"func main() {const (a = iota   //0b          //1    没有初始化则和上一行一样,相当于 b = iotac          //2d = "ha"   //独立值,iota += 1e          //"ha"   iota += 1f = 100    //iota +=1g          //100  iota +=1h = iota   //7,恢复计数i          //8)fmt.Println(a,b,c,d,e,f,g,h,i)
}

运算符

Go 语言内置的运算符有:

  • 算术运算符
  • 关系运算符
  • 逻辑运算符
  • 位运算符
  • 赋值运算符
  • 其他运算符:&返回变量存储地址;* 指针变量

运算符优先级

二元运算符的运算方向均是从左至右

1:||

2:&&

3:== != < >=

4:+ - | ^

5:* / % > & &^

条件语句

其它都同Java和C语言

  • Go 没有三目运算符,所以不支持 ?: 形式的条件判断
  • select语句:类似于 switch 语句,但是select会随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行

循环语句

for循环大括号内的三部分,如果第一个和第三个都省略,则分号也可以省略

函数

  • Go 语言最少有个 main() 函数
  • Go 函数可以返回多个值
  • Go 语言标准库提供了多种可动用的内置的函数。例如,len() 函数可以接受不同类型参数并返回该类型的长度。如果我们传入的是字符串则返回字符串的长度,如果传入的是数组,则返回数组中包含的元素个数
  • 在 Go 语言中,函数可是一等公 民。它既可以被独立声明,也可以被作为普通的值来传递或赋予变量。除此之外,我们还可 以在其他函数的内部声明匿名函数并把它直接赋给变量

函数式编程:我们可以通过“把函数传给函数”以及“让函 数返回函数”来编写高阶函数,也可以用高阶函数来实现闭包

函数声明与定义

//函数声明
type function_name func( [parameter list] ) [return_types]
//函数定义
func function_name( [parameter list] ) [return_types] {函数体
}
//parameter list参数列表,必须用圆括号包围
//return_types结果列表,如果有多个也要用圆括号包围

函数的签名

就是函数的参数列表和结果列表的统称,各个参数和结果的名称不能算作函数签名的一部分,甚至对于结果声明来说,没有名称都可以

只要两个函数的参数列表和结果列表中的元素顺序及其类型是一致的,我们就可以说它们是 一样的函数,或者说是实现了同一个函数类型的函数

函数定义解析

  • func:函数由 func 开始声明
  • function_name:函数名称,参数列表和返回值类型构成了函数签名。
  • parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
  • return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。
  • 函数体:函数定义的代码集合。

函数参数

  1. 值传递:值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
  2. 引用传递:引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

默认情况下,GO语言使用的是值传递

函数用法

函数作为另外一个函数的实参:函数定义后可作为另外一个函数的实参数传入

闭包:匿名函数,可在动态编程中使用

方法:方法是一个包含了接收者的函数

高阶函数

特点(满足其一即可):

1. 接受其他的函数作为参数传入

2. 把其他的函数作为结果返回

闭包

在一个函数中存在对外来标识符的引用。所谓的外来标识 符,既不代表当前函数的任何参数或结果,也不是函数内部声明的,它是直接从外边拿过来 的。还有个专门的术语称呼它,叫自由变量,可见它代表的肯定是个变量。

如果它是个 常量则形成不了闭包了,因为常量是不可变的程序实体,而闭包体现的却是由“不确 定”变为“确定”的一个过程。闭包函数就是因为引用了自由变量,而呈现出了一种“不确 定”的状态,也叫“开放”状态。 也就是说,它的内部逻辑并不是完整的,有一部分逻辑需要这个自由变量参与完成,而后者 到底代表了什么在闭包函数被定义的时候却是未知的。 即使对于像 Go 语言这种静态类型的编程语言而言,我们在定义闭包函数的时候最多也只能 知道自由变量的类型。

方法(go中的面向对象)

语法

  1. 方法是与特定类型(通常是结构体类型)关联的函数。方法具有接受者(receiver),这个接收者可以是值接收者或者指针接收者(不能是接口类型)。方法可以在方法内部访问接受者。
  2. 一个数据类型关联的所有方法,共同组成了该类型的方法集合(相当于面向对象中封装到类中的方法)。同一个方法 集合中的方法不能出现重名。并且,如果它们所属的是一个结构体类型,那 么它们的名称与该类型中任何字段的名称也不能重复。

       我们可以把结构体类型中的一个字段看作是它的一个属性或者一项数据,再 把隶属于它的一个方法看作是附加在其中数据之上的一个能力或者一项操 作。将属性及其能力(或者说数据及其操作)封装在一起,是面向对象编程 的一个主要原则。 Go 语言摄取了面向对象编程中的很多优秀特性,同时也推荐这种封装的做 法。从这方面看,Go 语言其实是支持面向对象编程的,但它选择摒弃了一些 在实际运用过程中容易引起程序开发者困惑的特性和规则。

3、接收者

      a.值类型

  • 值类型的变量可以调用值接收者的方法,因为值接收者的方法会复制该变量,然后在复制的副本上操作。
  • 值类型的变量也可以调用指针接收者的方法,但这样会隐式地将值类型转换为指针类型。

       b.指针类型

  • 指针类型的变量可以调用指针接收者的方法,指针方法的接收者是该方法所属的那个基本类型值的指针值的一个副本,在方法内对该副本指向的值进行修改,一定会体现在原值上
  • 指针类型的变量也可以调用值接收者的方法,但这样会隐式地解引用指针,并将指向的数据复制到一个新的变量中,然后调用该方法。

        一个自定义数据类型的方法集合中仅会包含它的所有值方法,而该类型的指针类型的方 法集合却囊括了前者的所有 方法,包括所有值方法和所有指针方法。

        严格来讲,我们在这样的基本类型的值上只能调用到它的值方法。但是,Go 语言会适时地为我们进行自动地转译,使得在值上也能调用到它的指针方法。

        比如,在Cat类型的变量cat之上,之所以我们可以通过cat.SetName("monster")修 改猫的名字,是因为 Go 语言把它自动转译为了(&cat).SetName("monster"), 即:先取cat的指针值,然后在该指针值上调用SetName方法。

//定义方法
func (receiver_name receiver_type) methodName(parameters) (results) {  // 方法体  
}// 定义一个结构体类型 Rectangle  
type Rectangle struct {  Width, Height float64  
}  // 为 Rectangle 类型定义一个方法来计算面积  
func (r Rectangle) Area() float64 {  return r.Width * r.Height  
}  

继承

结构体中的匿名字段相当于该结构体的父类,该结构体(子类)可以调用匿名字段(父类)的方法。

如果匿名字段实现了一个方法,那么包含这个匿名字段的结构体也能调用该方法。

重写

接受者为父类的方法,将其接收者改为子类,并重写方法体,即可实现方法的重写。

存在继承关系时,按照就近原则,进行调用(子类调用方法时,先考虑子类的方法,子类没有再去父类寻找)


http://www.ppmy.cn/server/134258.html

相关文章

ansible————task控制

一、loop循环 当某一个操作需要多次执行的时候&#xff0c;就需要用到循环 1、循环语句 安装多个安装包&#xff0c;启动多个应用 [rootcontrol ansible_manage]# cat play_book/loop.yaml --- - name: loop exercisehosts: manage1vars_files:- var/loop_var.yamltasks:-…

K8S---02.Kubernetes的pod

1 命名空间操作 命名空间的作用是为了 隔离资源 理解成对资源进行分类。 名称&#xff1a;namespace 简写&#xff1a;ns 默认命名空间为“default” 1.1 创建命名空间 kubectl create ns 命名空间名称 kubectl create ns my-ns 、 1.2 查看命名空间 kubectl get names…

【Python数据可视化】利用Matplotlib绘制美丽图表!

【Python数据可视化】利用Matplotlib绘制美丽图表&#xff01; 数据可视化是数据分析过程中的重要步骤&#xff0c;它能直观地展示数据的趋势、分布和相关性&#xff0c;帮助我们做出明智的决策。在 Python 中&#xff0c;Matplotlib 是最常用的可视化库之一&#xff0c;它功能…

【Android】图片点击放大放小

&#x1f4d6;Android图片点击放大放小 ✅1.触摸缩放✅2.缩放移动中心 ✅1.触摸缩放 通过触摸事件获取触摸的坐标&#xff0c;并将其通过动画放大缩小即可实现&#xff1a; 这里的holder.photo_id换成图片组件即可。 private boolean isScalefalse;holder.photo_id.setOnTouch…

10.23学习日志

1.概念 Matplotlib 库&#xff1a;是一款用于数据可视化的 Python 软件包&#xff0c;支持跨平台运行&#xff0c;它能够根据 NumPy ndarray 数组来绘制 2D 图像&#xff0c;它使用简单、代码清晰易懂 Figure&#xff1a;指整个图形&#xff0c;您可以把它理解成一张画布&…

《深度学习》OpenCV LBPH算法人脸识别 原理及案例解析

目录 一、LBPH算法 1、概念 2、实现步骤 3、方法 1&#xff09;步骤1 • 缩放 • 旋转和平移 2&#xff09;步骤2 二、案例实现 1、完整代码 1&#xff09;图像内容&#xff1a; 2&#xff09;运行结果&#xff1a; 一、LBPH算法 1、概念 在OpenCV中&#xff0c;L…

MySQL启动报错:InnoDB: Unable to lock ./ibdata1 error

MySQL启动报错&#xff1a;InnoDB: Unable to lock ./ibdata1 error 在OS X环境下MySQL启动时报错&#xff1a; 016-03-03T00:02:30.483037Z 0 [ERROR] InnoDB: Unable to lock ./ibdata1 error: 35 2016-03-03T00:02:30.483100Z 0 [Note] InnoDB: Check that you do not alr…

【VUE】Vue中常用的修饰符

事件修饰符 .stop&#xff1a;阻止事件冒泡。.prevent&#xff1a;阻止默认事件。.capture&#xff1a;使用事件捕获模式。.self&#xff1a;只当事件在该元素本身&#xff08;比如不是子元素&#xff09;触发时触发回调。.once&#xff1a;只触发一次事件。 按键修饰符 .en…