二.基础语法

1.Hello World

`package main` 

`import "fmt"//导入一个fmt用来输出的`

`func main() {`
    `fmt.Println("Hello, 世界")//打印输出 hello world字符串!`
`}`

Go 是一门编译语言,Go 语言工具链将源代码及其依赖转换成计算机机器指令(译注:静态编译)。Go 语言提供的工具通过一个单独的命令 go 调用go 命令有一系列命令。最简单的一个子命令就是 run这个命令编译一个或多个以。.go 结尾的源文件链接文件,并运行最终生成可执行文件。(本书使用$表示命令行提示符。)

$ go run helloworld.go

输出

Hello, 世界

2.命名

2.1命名

Go语言中的函数名、变量名常量名、类型名、语句标号包名等所有的命名,都遵循一个简单命名规则:一个名字必须以一个字母(Unicode字母)或下划线开头,后面可以任意数量的字母数字下划线大写字母小写字母不同的:heapSort和Heapsort两个不同的名字

Go语言中类似if和switch关键字有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

此外,还有大约30多个定义名字比如inttrue等,主要对应内建的常量类型函数

内建常量: true false iota nil

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

内建函数: make len cap new append copy close delete
          complex real imag
          panic recover
2.2声明

声明语句定义了程序的各种实体对象以及部分或全部的属性。Go语言主要有四种类型声明语句varconst、typefunc,分别对应变量常量类型函数实体对象声明

一个Go语言编写程序对应一个或多个以.go为文件后缀名源文件每个源文件中以包的声明语句开始,说明源文件属于哪个包。包声明语句之后是import语句导入依赖的其它包,然后是包一级的类型变量常量函数声明语句,包一级的各种类型声明语句的顺序无关紧要(译注:函数内部名字则必须先声明之后才能使用

3.变量

3.1变量声明

var声明语句可以创建一个特定类型变量然后变量加一名字,并且设置变量初始值。变量声明的一般语法如下

var 变量名字 类型 = 表达式

其中“类型”或“= 表达式”两个部分可以省略其中的一个。如果省略的是类型信息,那么将根据初始化表达式推导变量的类型信息。如果初始化表达式省略,那么将用零值初始化该变量。 数值类型变量对应的零值是0,布尔类型变量对应的零值是false字符串类型对应的零值是空字符串,接口引用类型(包括slice指针mapchan和函数)变量对应的零值是nil数组结构体等聚合类型对应的零值是每个元素字段都是对应该类型的零值。

Go语言的数据类型默认零值如下所示

数据类型 默认零值
bool false
int 0
float (0+0i)
string “”
array 数组元素类型的零值
map nil
struct 结构体中每个字段的零值
interface nil
function nil

需要注意的是,对于结构体和数组类型,默认零值是指结构体中每个字段或数组中每个元素的零值。而对于map类型,默认零值是nil,表示映射。另外,所有类型的默认值均为其零值,除了bool类型没有默认值,注意在go语言中没有double类型。

零值初始化机制可以确保每个声明的变量总是有一个良好定义的值,因此在Go语言中不存在未初始化的变量。这个特性可以简化很多代码,而且可以在没有增加额外工作的前提下确保边界条件下的合理行为例如

var s string
fmt.Println(s) // ""

这段代码打印一个空字符串,而不是导致错误或产生不可预知的行为。Go语言程序员应该让一些聚合类型的零值也具有意义,这样可以保证不管任何类型的变量总是有一个合理有效的零值状态

可以在一个声明语句中同时声明一组变量,或用一组初始化表达式声明并初始化一组变量。如果省略每个变量的类型,将可以声明多个类型不同的变量(类型由初始化表达式推导):

var i, j, k int                 // int, int, int
var b, f, s = true, 2.3, "four" // bool, float64, string

初始化表达式可以是字面量或任意的表达式。在包级别声明的变量会在main入口函数执行完成初始化,局部变量将在声明语句被执行到的时候完成初始化。

一组变量也可以通过调用一个函数,由函数返回多个返回值初始化:

var f, err = os.Open(name) // os.Open returns a file and an error
package main

import "fmt"

func main() {

	var(
		name string
		age	 int
		addr string
		)
		//string值默认为空
		//int  默认值:0
		fmt.Println(name,age,addr)
}

}

通过以上代码例子我们可以看到go语言支持批量定义声明

3.2简短变量声明

在函数内部,有一种称为简短变量声明语句的形式可用于声明和初始化局部变量。它以“名字 := 表达式”形式声明变量,变量的类型根据表达式来自动推导。下面是lissajous数中的三个简短变量声明语句:

anim := gif.GIF{LoopCount: nframes}
freq := rand.Float64() * 3.0
t := 0.0
package main
import "fmt"
func main(){
	name:="yjh"
	age :=18
    //:= 自动推导
    fmt.Println(name,age)
		}

这是Go语言的推导声明写法编译器自动根据右值类型推断出左值的对应类型。

它可以自动的推导出一些类型,但是使用也是有限制的;

因为简洁和灵活的特点,简短变量声明被广泛用于大部分局部变量的声明和初始化。var形式的声明语句往往是用于需要显式指定变量类型的地方,或者因为变量稍后会被重新赋值而初始值无关紧要的地方。

i := 100                  // an int
var boiling float64 = 100 // a float64
var names []string
var err error
var p Point

和var形式声明语句一样,简短变量声明语句也可以用来声明和初始化一组变量:

i, j := 0, 1

但是这种同时声明多个变量的方式应该限制只在可以提高代码可读性的地方使用比如for语句的循环的初始化语句部分

var形式的声明语句往往是用于需要显示指定变量类型地方,或者因为变量稍后会被重新赋值而初始值无关紧要的地方。

当一个变量被声明之后,如果没有显示的给他赋值,系统自动赋予它类型的零值:

3.3变量赋值
  1. Go语言中变量的赋值有以下几种方式

    需要注意的是,赋值操作从右往左进行的,即先计算等号右侧的表达式,然后将其赋值给左侧的变量。如果左右两侧的类型不匹配编译器报错

3.4匿名变量

在Go语言中,匿名变量是使用_表示特殊变量,也被称为“占位符”或“空标识符”。匿名变量可以用在函数返回值、变量赋值、结构体中的成员赋值等场合。

使用匿名变量时,可以省略变量名,从而避免了对变量名的定义和使用,减少了代码量和命名冲突可能性。同时,由于匿名变量不会分配内存,因此不会产生内存浪费问题

下面是一些匿名变量的使用场景

  1. 函数返回值中的匿名变量

如果一个函数返回多个值,但是我们需要其中的某些值,可以使用匿名变量来忽略需要返回值。示例代码:

func test() (int, string) {
    return 10, "hello"
}

x, _ := test()

在上面的代码中,我们只需要函数test返回第一个值,因此用匿名变量_忽略第二个返回值

  1. 忽略变量赋值中的某些值

时候我们在进行变量赋值时,不需要使用某些返回值。这时候可以使用匿名变量来忽略这些值。示例代码:

var a int
a, _, _ = 1, 2, 3

在上面的代码中,我们用匿名变量_忽略了赋值语句中的第二个第三个值。

  1. 结构体中的匿名字段

在结构体中,如果某个字段的类型是匿名的,那么该字段可以被称为匿名字段。可以通过结构体的匿名字段来访问该字段所属的结构体中的其他字段。示例代码:

type Person struct {
    Name string
    Age int
}

type Student struct {
    Person
    Score float64
}

var s Student
s.Name = "Tom"
s.Age = 18
s.Score = 90.5

在上面的代码中,结构体Student中有一个匿名字段Person,可以通过s.Names.Age访问Person结构体中的字段。

需要注意的是,在使用匿名变量时,虽然可以省略变量名,但是需要保留变量类型。否则会出现编译错误

4.常量

在Go语言中,常量是指在程序运行期间不可改变的值。常量可以在编译期间计算,可以用于减少代码中的魔法数值、提高程序的可读性和可维护性。(注:在代码中,有些数字可能没有直观的含义,例如3600表示一小时有多少秒,1024表示2的10次方等等。这些数字称为魔法数值”,因为它们的意义不明确,需要在代码中寻找上下文理解。)

在Go语言中,常量的定义使用关键字const,常量名一般使用大写字母,多个单词之间使用下划线分隔。常量的值可以是数字字符串、布尔值等。

常量定义的语法如下

const name = value

下面是一些常量的例子

const Pi = 3.14159
const Greeting = "Hello, World!"
const MaxInt32 = 1<<31 - 1
const Debug = false

在上面的例子中,我们定义了几个常量。Pi常量的值是浮点数3.14159Greeting常量的值是字符"Hello, World!"MaxInt32常量的值是整数2^31-1Debug常量的值是布尔值false

常量还可以使用iota来进行自增,它用于枚举、位运算场景iota的初始值为0,每出现一次iota,它的值就自增1。下面是一个枚举例子

package main

import "fmt"

const (
    Monday = iota
    Tuesday
    Wednesday
    Thursday
    Friday
    Saturday
    Sunday
)

func main() {
    fmt.Println(Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday)
}

在上面的例子中,我们使用iota定义了一组枚举常量。Monday的值是0Tuesday的值是1,以此类推。我们可以在fmt.Println打印这些常量的值,输出结果0 1 2 3 4 5 6

总之,Go语言的常量可以提高程序的可读性和可维护性,可以减少代码中的魔法数值。在定义常量时,需要注意常量的命名规则和常量值的类型。

5类型

5.1Go语言中的类型

Go语言中的类型分为基本类型和复合类型两种。下面分别列举并说明

基本类型 说明
bool 布尔型,值为truefalse
uint8 8位无符号整型取值范围为0到255
uint16 16位无符号整型取值范围为0到65535
uint32 32位无符号整型取值范围为0到4294967295
uint64 64位无符号整型取值范围为0到18446744073709551615
int8 8位有符号整型取值范围为-128到127
int16 16位有符号整型取值范围为-32768到32767
int32 32位有符号整型取值范围为-2147483648到2147483647
int64 64位有符号整型取值范围为-9223372036854775808到9223372036854775807
float32 32位浮点型,可以表示小数精度为7位小数
float64 64位浮点型,可以表示小数精度为15位小数
byte 8位无符号整型,与uint8相同
rune 32位有符号整型,表示一个Unicode码点
uintptr 无符号整型,用于存放一个指针地址
复合类型 说明
string 字符串类型,由一串Unicode码点组成
array 数组类型,元素类型相同长度固定
slice 切片类型,可以动态增长缩小长度
map 映射类型,键值对类型
struct 结构体类型,由若干个字段组成,每个字段可以是任意类型
interface 接口类型,可以包含任意类型的值
channel 通道类型,用于在多个goroutine之间传递数据

需要注意的是,Go语言还支持类型别名,可以用type关键字现有的类型定义一个别名。例如:

type MyInt int // 将int类型定义为MyInt类型的别名

类型别名在代码维护和兼容性方面有一定的作用

总的来说,Go语言的类型非常丰富,支持基本类型和复合类型,可以满足各种编程需求。同时,Go语言的类型系统非常强

5.2go语言的格式化输出

Go语言中的格式化输出是通过fmt实现的,它支持格式化动词与C语言中的printf函数类似,但也有一些不同之处。

下面是几个常用的格式化动词及其含义:

除了动词之外,还可以使用一些修饰符控制输出格式,如:

下面是一些例子展示如何使用格式化输出:

package main

import "fmt"

func main() {
    x := 123
    y := 3.14159
    s := "hello"

    fmt.Printf("x=%d, y=%f, s=%sn", x, y, s)
    fmt.Printf("x=%5d, y=%6.2f, s=%sn", x, y, s)
}

输出:

x=123, y=3.141590, s=hello
x=  123, y=  3.14, s=hello

在上面的例子中,fmt.Printf函数使用格式化字符串来格式化输出。在格式化字符串中,%d表示整数%f表示浮点数%s表示字符串。使用%d%f时,需要将要输出的值作为参数传递fmt.Printf函数,使用%s时,直接将要输出的字符串作为参数传递即可

值得注意的是,使用fmt.Printf函数时,输出格式的字符串和参数表中的值一一对应,如果不匹配会导致运行错误。此外,fmt.Printf函数还有其他一些格式化输出相关的函数,如fmt.Sprintffmt.Fprintf等,使用方式fmt.Printf类似。

6 go语言的作用域

Go语言中的作用域是指一个标识符(变量、常量、函数等)在程序中可被访问范围标识符的作用域由它在程序中的声明位置和所在代码块(包括函数、if语句、for循环等)的限制来确定

Go语言中的作用域规则如下:

  • 如果一个标识符在函数内声明,那么它的作用域只限于这个函数内部。
  • 如果一个标识符在函数外声明,那么它的作用域可以是整个包内,也可以是跨包访问公共标识符。
  • 如果一个标识符在代码块内部声明(如if语句、for循环等),那么它的作用域只限于这个代码块内部。
  • 在同一作用域内不能定义重名的标识符。
  • 嵌套的代码块中,内部的代码块可以访问外部的代码块中声明的标识符,但外部的代码块不能访问内部的代码块中声明的标识符。

下面是一些例子展示了不同作用域的标识符的声明和使用方式

package main

import "fmt"

var x = 10 // 在包级别声明一个变量x

func foo() {
    var y = 20 // 在函数内部声明一个变量y

    if x := 100; x > y { // 在if语句中声明一个变量x
        fmt.Println(x) // x的作用域限于if语句块内
    } else {
        fmt.Println(y) // y的作用域限于foo函数块内
    }

    fmt.Println(x) // x可以在foo数中访问
    fmt.Println(y) // y可以在foo数中访问
}

func main() {
    foo()
    fmt.Println(x) // x可以在整个包中访问
}

在上面的例子中,变量x在包级别声明,可以在整个包中访问。变量y在函数内部声明,只能在函数内部访问。在foo函数内部,if语句中声明了一个新的变量x,它的作用域限于if语句块内。在foo函数内部,可以访问变量xy。在main数中,可以访问包级别声明的变量x

总之,Go语言的作用域规则比较简单明了,但需要注意标识符的声明位置和所在代码块的限制,以避免出现作用域错误

原文地址:https://blog.csdn.net/qq_55706127/article/details/130713305

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_35710.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注