Go 语言基础语法

Go 语言基础语法,第1张

文章目录 一、GO 语言结构1. 基础组成2. 实例3. 执行 Go 程序 二、Go 语言基础语法1. Go 标记2. 行分隔符3. 注释4. 标识符5. 字符串连接6. 关键字7. Go 语言的空格8. 格式化字符串 三、Go 语言数据类型1. 分类2. 数字类型3. 浮点型4. 其他数字类型 四、Go 语言变量1. 变量声明2.变量声明方法3. 多变量声明4. 值类型和引用类型4.1 内存的压栈4.2 内存的堆4.3 示例 5. 变量的作用域6. 简短形式,使用 := 赋值 *** 作符7. 空白标识符 五、常量1. 什么是常量2. 示例3. iota


一、GO 语言结构 1. 基础组成
包声明
引入包
函数
变量
语句&表达式
注释
2. 实例
package main

import "fmt"

func main() {
   /* 这是我的第一个简单的程序 */
	fmt.Println("hello world!")
}

第一行代码 package main 定义了包名。你必须在源文件中非注释的第一行指明这个文件属于哪个包,如:package main。package main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包。

下一行 import "fmt" 告诉 Go 编译器这个程序需要使用 fmt 包(的函数,或其他元素),fmt 包实现了格式化 IO(输入/输出)的函数。

下一行 func main() 是程序开始执行的函数。main 函数是每一个可执行程序所必须包含的,一般来说都是在启动后第一个执行的函数(如果有 init() 函数则会先执行该函数)。

下一行/*...*/是注释,在程序执行时将被忽略。单行注释是最常见的注释形式,你可以在任何地方使用以 // 开头的单行注释。多行注释也叫块注释,均已以 /* 开头,并以 */ 结尾,且不可以嵌套使用,多行注释一般用于包的文档描述或注释成块的代码片段。

下一行 fmt.Println(...) 可以将字符串输出到控制台,并在最后自动增加换行字符 \n。
使用 fmt.Print(“hello, world\n”) 可以得到相同的结果。
Print 和 Println 这两个函数也支持使用变量,如:fmt.Println(arr)。如果没+有特别指定,它们会以默认的打印格式将变量 arr 输出到控制台。

当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出;标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的。

3. 执行 Go 程序

执行go run test.go可以看到输出为hello world!
执行go build test.go可以生成二进制文件test.exe

二、Go 语言基础语法 1. Go 标记

Go 程序可以由多个标记组成,可以是
关键字,标识符,常量,字符串,符号

如以下 GO 语句由 6 个标记组成:

fmt.Println("Hello, World!")

//6 个标记是(每行一个):

fmt
.
Println
(
"Hello, World!"
)
2. 行分隔符

在 Go 程序中,一行代表一个语句结束

如果你打算将多个语句写在同一行,它们则必须使用;人为区分,但在实际开发中我们并不鼓励这种做法

以下为两个语句:

fmt.Println("Hello, World!")
fmt.Println("百度:baidu.com")
3. 注释

注释不会被编译,每一个包应该有相关注释

单行注释是最常见的注释形式,你可以在任何地方使用以//开头的单行注释。

多行注释也叫块注释,均已以/*开头,并以*/结尾。

// 单行注释
/*
 你好
 欢迎来南京
 */
4. 标识符 标识符用来命名变量、类型等程序实体一个标识符实际上就是一个或是多个字母(A~Z和a~z)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字
//以下是有效的标识符
mahesh   kumar   abc   move_name   a_123
myname50   _temp   j   a23b9   retVal
//以下是无效的标识符
1ab(以数字开头)
case(Go 语言的关键字)
a+b(运算符是不允许的)
5. 字符串连接

Go 语言的字符串可以通过 +实现:

实例

package main
import "fmt"
func main() {
    fmt.Println("hello" + "world")
}

//以上实例输出结果为:

helloworld
6. 关键字 下面列举了 Go 代码中会使用到的 25 个关键字或保留字:
.....
breakdefaultfuncinterfaceselect
casedefergomapstruct
chanelsegotopackageswitch
constfallthroughifrangetype
continueforimportreturnvar
除了以上介绍的这些关键字,Go 语言还有 36 个预定义标识符:
.....
appendboolbytecapclose
copyfalsefloat32float64imag
int32int64iotalenmake
printprintlnrealrecoverstring

程序一般由关键字、常量、变量、运算符、类型和函数组成。

程序中可能会使用到这些分隔符:括号 (),中括号 [] 和大括号 {}

程序中可能会使用到这些标点符号:. , ; :

7. Go 语言的空格 Go 语言中变量的声明必须使用空格隔开
var age int;
//语句中适当使用空格能让程序更易阅读

//无空格:
fruit=apples+oranges;

//在变量与运算符间加入空格,程序看起来更加美观,如:
fruit = apples + oranges; 
8. 格式化字符串 Go 语言中使用 fmt.Sprintf 格式化字符串并赋值给新串
package main

import (
	"fmt"
)

func main() {
   // %d 表示整型数字,%s 表示字符串
	var age = 18
	var time = "2022-3-15"
	var url = "age=%d,time=%s"
	var target_url = fmt.Sprintf(url, age, time)
	fmt.Println(target_url)
}

输出结果为:

age=18,time=2022-3-15

常用的占位符

格式化指令含义
%%%字面量
%b将一个整数格式转化为二进制的表达方式
%c相应Unicode码点对应所表示的字符
%d十进制整数
%o八进制整数
%x小写的十六进制数值
%X大写的十六进制数值
%U一个Unicode表示法表示的整型码值
%s输出以原生的UTF8字节表示的字符,如果console不支持utf8编码,则会乱码
%t以true或者false的方式输出布尔值
%v使用默认格式输出值,或者如果方法存在,则使用类性值的String()方法输出自定义值
%T输出值的类型
三、Go 语言数据类型 1. 分类

在 Go 编程语言中,数据类型用于声明函数和变量

数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存

Go 语言按类别有以下几种数据类型:

|类型 |描述|
|–|–|–|
|布尔型|布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true。 |
|数字类型 |整型 int 和浮点型 float32、float64,Go 语言支持整型和浮点型数字,并且支持复数,其中位的运算采用补码。 |
|字符串类型|字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本。 |
|派生类型|包括:指针类型(Pointer)、数组类型、结构化类型(struct)、Channel 类型、函数类型、切片类型、接口类型(interface)、Map 类型 |

2. 数字类型

Go 也有基于架构的类型,例如:int、uint 和 uintptr。

类型描述
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)
3. 浮点型
类型描述
float32IEEE-754 32位浮点型数
float64IEEE-754 64位浮点型数
complex6432 位实数和虚数
complex12864 位实数和虚数

带小数点的是浮点型,不带小数点的是整形

4. 其他数字类型 以下列出了其他更多的数字类型:
类型描述
byte类似 uint8
rune类似 int32
uint32 或 64 位
int与 uint 一样大小
uintptr无符号整型,用于存放一个指针
四、Go 语言变量

变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念,变量可以通过变量名访问

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

1. 变量声明 声明变量的一般形式是使用 var 关键字
var identifier type

//可以一次声明多个变量:
var identifier1, identifier2 type
实例
package main

import "fmt"

func main() {
	var a string = "hello"
	fmt.Println(a)

	var b, c int = 1, 2
	fmt.Println(b, c)
}

//输出结果如下
hello
1 2
2.变量声明方法

第一种,指定变量类型,如果没有初始化,则变量默认为零值

var v_name v_type
v_name = value
package main

import "fmt"

func main() {
	//声明一个变量并初始化
	var a = "goroute"
	fmt.Println(a)

	//没有初始化就为零
	var b int
	fmt.Println(b)

	//布尔值零值为false
	var c bool
	fmt.Println(c)
}


//输出的结果如下
goroute
0
false
数值类型(包括complex64/128)为 0

布尔类型为 false

字符串为 ""(空字符串)

第二种,根据值自行判定变量类型

var v_name = value
package main

import "fmt"

func main() {
	var a = true
	fmt.Println(a)
}

//输出结果如下
true

第三种,如果变量已经使用 var 声明过了,再使用 := 声明变量,就产生编译错误

package main

import "fmt"

func main() {
	a := 1
	fmt.Println(a)
}

//此时不会产生编译错误,因为有声明新的变量,因为 := 是一个声明语句
a := 1 相等于:
var a int 
a =1 
可以将 var a string = “hello” 简写为 a := “hello”
package main

import "fmt"

func main() {
	//相当于var a string = "hello"
	a := "hello"
	fmt.Println(a)
}
3. 多变量声明 类型相同多个变量, 非全局变量
package main

import "fmt"

func main() {
	a, b, c := 1, 2, 3
	fmt.Println(a, b, c)
}
因式分解法
// 这种因式分解关键字的写法一般用于声明全局变量

var(
	test1 int
	test2 float32
	test3 string
)
实例
package main

import "fmt"

var x, y int

var (
	a int
	b bool
)

var c, d int = 1, 2

var e, f = 666, "hello world!"

func main() {
	//这种不带声明格式的只能在函数体中出现
	g, h := 7878, "happy"
	fmt.Println(x, y, a, b, c, d, e, f, g, h)
}


//输出结果如下
0 0 0 false 1 2 666 hello world! 7878 happy
4. 值类型和引用类型 所有像 intfloatboolstring 这些基本类型都属于值类型,使用这些类型的变量直接指向存在内存中的值:

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

可以通过 &i 来获取变量 i 的内存地址,例如:0xf840000040(每次的地址都可能不一样)

值类型变量的值存储在堆中

内存地址会根据机器的不同而有所不同,甚至相同的程序在不同的机器上执行后也会有不同的内存地址。因为每台机器可能有不同的存储器布局,并且位置分配也可能不同

更复杂的数据通常会需要使用多个字,这些数据一般使用引用类型保存

一个引用类型的变量 r1 存储的是 r1 的值所在的内存地址(数字),或内存地址中第一个字所在的位置。

这个内存地址称之为指针,这个指针实际上也被存在另外的某一个值中

同一个引用类型的指针指向的多个字可以是在连续的内存地址中(内存布局是连续的),这也是计算效率最高的一种存储形式;也可以将这些字分散存放在内存中,每个字都指示了下一个字所在的内存地址。

当使用赋值语句 r2 = r1 时,只有引用(地址)被复制。

如果 r1 的值被改变了,那么这个值的所有引用都会指向被修改后的内容,在这个例子中,r2 也会受到影响。

4.1 内存的压栈

压栈的顺序:先进后出

函数加入栈后,会执行赋值

d栈:变量的释放

4.2 内存的堆

堆的顺序:先进先出

4.3 示例
package main

import "fmt"

//变量在内存中的存储方式

var num int = 10
var sun int = 20

func main() {

	var test1 = "hello"
	var test2 = "world"

	fmt.Println("num=", num)
	//调用内存地址使用&
	fmt.Println("num的内存地址是", &num)
	fmt.Println("sun的内存地址是", &sun)
	//调用函数中中变量
	fmt.Println(test1)
	fmt.Println(test2)
}


//输出结果如下
num= 10
num的内存地址是 0x709258
sun的内存地址是 0x709260
hello
world

上面代码中,在全局定义的变量是存放在栈中的,他是属于文件的

var num int = 10
var sun int = 20

而局部变量则是存放在堆中,是属于main函数的

	var test1 = "hello"
	var test2 = "world"

当全局变量加载完以后会加载main函数,但是main函数中定义的变量并不会被压栈,而是会被放入堆中

在test函数中是无法调用main函数中的变量的,存放位置是不同的

函数中的变量会随着函数的结束而结束它的生命周期

5. 变量的作用域

在函数内部声明的变量教局部变量,生命周期仅限于函数内部

在函数外部声明的变量交全局变量,生命周期作用于整个包,如果是大写首字母,则作用域整个程序

语句块中的变量,生命周期仅限于语句块,语句块外部不能被识别

示例

package main

import "fmt"

//定义全局变量
var a string = "10"

func main() {
	n()
	m()

	fmt.Println("主函数输出:", a)
}

func n() {
	println("n函数输出:", a)
}

func m() {
	a := "0"
	fmt.Println("m的函数输出:", a)
}


//输出结果如下
n函数输出: 10
m的函数输出: 0
主函数输出: 10
6. 简短形式,使用 := 赋值 *** 作符 查看变量的数据类型
package main

import "fmt"

/*
:=
定义即声明,无需写var,系统会自动推断数据类型,无需自定义数据类型
格式只能在函数体内
*/

func main() {
	num := "hello"
	fmt.Println(num)
	//查看变量的数据类型
	fmt.Printf("num的数据类型是:%T", num)
}

//输出结果为
hello
num的数据类型是:string
7. 空白标识符

空白标识符_ 也被用于抛弃值,如值5_,b=5,7中被抛弃

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

并行赋值也被用于当一个函数返回多个返回值时,比如这里的 val 和 错误 err 是通过调用Func1 函数同时得到:val,err = Func(var1)

package main

import "fmt"

func main() {
	_, numb, strs := numbers() //只获取函数返回值的后两个
	fmt.Println(numb, strs)
}

func numbers() (int, int, string) {
	a, b, c := 1, 2, "str"
	return a, b, c
}

//输出结果如下
2 str
五、常量 1. 什么是常量

常量是一个简单值的标识符,使用 const 修饰,是程序在运行时,不会被修改的量

常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。

常量的定义格式:

const identifier [type] = value

//可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型

//显式类型定义: 
const b string = "abc"

//隐式类型定义: 
const b = "abc"

//多个相同类型的声明可以简写为:
const c_name1, c_name2 = value1, value2
2. 示例
package main

import "fmt"

func main() {
	const LENGTH int = 10
	const WIDTH int = 5
	var area int
	const a, b, c = 1, false, "str" //多重赋值

	area = LENGTH * WIDTH
	fmt.Printf("面积为 : %d", area)
	fmt.Println()
	fmt.Println(a, b, c)
}

//输出结果如下
面积为 : 50
1 false str
常量可以用len(), cap(), unsafe.Sizeof()函数计算表达式的值。常量表达式中,函数必须是内置函数,否则编译不过:
package main

import (
	"fmt"
	"unsafe"
)

const (
	a = "abc"
	b = len(a)
	c = unsafe.Sizeof(a)
)

func main() {
	fmt.Println(a, b, c)
}

//输出结果如下
abc 3 16
3. iota

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

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

iota 可以被用作枚举值:

const (
    a = iota
    b = iota
    c = iota
)

//第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1;
//所以 a=0, b=1, c=2 可以简写为如下形式:

const (
    a = iota
    b
    c
)
示例 ①
package main

import "fmt"

func main() {
	const (
		//iota相当于索引,从0开始
		a = iota //0
		b        //1
		c        //2
	)
	fmt.Println(a, b, c)
}

//输出结果
0 1 2
示例 ②
//求半径为5的圆的面积和周长
//面积=Π*半径²
//周长=2*Π*半径

package main

import "fmt"

func main() {
	const Π float32 = 3.14
	var r float32 = 5
	//周长a
	a := 2 * Π * r
	//面积
	s := Π * r * r
	fmt.Println("周长:", a, "\n面积:", s)
}


//输出结果为
周长: 31.400002 
面积: 78.5
案例 ③
//求出2的指数次方结果
package main

import "fmt"

func main() {
	const (
		a = 1 << iota //往左移0位
		b = 2 << iota //往左移1位
		c             //往左移2位
		d             //往左移3位
		e             //往左移4位
	)
	fmt.Println(a, b, c, d, e)
}

//输出结果如下
1 4 8 16 32
案例 ④
//写一个程序获得当前运行系统中go的工作目录和项目目录路径,并输出在终端
package main

import (
	"fmt"
	"os"
)

func main() {
	//获取系统参数,go的工作目录
	var home string = os.Getenv("GOROOT")
	fmt.Println("go的工作目录是:", home)
	//获取go的项目目录
	var project string = os.Getenv("GOPATH")
	fmt.Println("go的项目目录是:", project)

}

//输出结果如下
go的工作目录是: D:\Go
go的项目目录是: D:\goproject
案例 ⑥
//定义两个常量 Man=1 和 Female=2,获取当前时间的秒数,如果能被Female整除,则在终端打印Female,否则打印Man
package main

import (
	"fmt"
	"time"
)

const (
	Female = 2
	Man    = 1
)

func main() {
	for {
		//获取当前时间戳
		sec := time.Now().Unix()
		if sec%Female == 0 {
			fmt.Println("Female")
		} else {
			fmt.Println("Man")
		}
		//1000毫秒=1秒
		time.Sleep(1000 * time.Millisecond)
	}
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/995417.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存