ps: 并不是一个小白入门,需要掌握
linux
,网络
,或者一名编程语言Go语言的基础语法
📅 2024年4月26日
📦 使用版本为
1.21.5
入门程序
⭐️和
java
类似,也是有包的概念,它的程序入口也是main
函数,如果一个go程序有main
函数,那么它的包一定就是main
包1️⃣ 在
Go
中,加不加;
都可以package main import "fmt" func main() { fmt.Println("Hello World"); };
2️⃣ 在命令行中可以执行
go run [go文件]
来直接运行,获取go build
3️⃣ 多个包可以合并导包
package main //导入多个包 import ( "fmt" "time" ) func main() { fmt.Println("Hello World") time.Sleep(1) }
4️⃣ 花括号必须和主体变量名在同一行(比较反人类的一点),这个是它的语法问题,强制代码风格
包
⭐️
go
的包和java
的差不多,在Go
语言中,一个包(package
)是由一组相关的源代码文件组成的,这些文件通常位于相同的目录下,共同服务于一个特定的目的。创建一个新的Go
文件(.go文件
)时,该文件即被视为该目录下现有包的一部分,或者如果该目录下还没有包,则创建了一个新的包在Go中,程序是通过将包链接在一起来构建的,也可以理解为最基本的调用单位是包,而不是go文件。包其实就是一个文件夹,包内共享所有源文件的变量,常量,函数以及其他类型。包的命名风格建议都是小写字母,并且要尽量简短
packge main //表示这个函数属于main包
导入
⭐️ 导入其实也和
Java/Python
差不多import "fmt" import e "fmt" //给包起别名
⭐️ 如果有多个包导入可以简写语法
import( "fmt" "match" )
⭐️ 或者只导入不调用,可以使用
_
来匿名调用import( "fmt" _ "match" //下划线表示匿名调用 )
⭐️ 在Go中完全禁止循环导入,不管是直接的还是间接的。例如包A导入了包B,包B也导入了包A,这是直接循环导入,包A导入了包C,包C导入了包B,包B又导入了包A,这就是间接的循环导入,存在循环导入的话将会无法通过编译
init函数
⭐️ 在导包后,如果存在
init
函数则对该函数进行定义,这是一个特殊的函数,每个含有该函数的包都会首先
执行这个函数⭐️ 变量除了可以在全局声明中初始化,也可以在
init
函数中初始化package main var a int var c int func init() { a = 1 c = 2 } func main() { println(a) println(c) }
⭐️ 一个包中可以含有多个
init
,但是一个源文件只能包含一个init
⭐️ 它主要定义可以在程序执行之前对程序进行检验和修复
导出
⭐️ 在
Go
中的访问控制和java
不同,它是直接通过命名来实现,首字母大小为对外暴露,首字母小写表示只对内部开放1️⃣ 在
var
包下新建了一个Test
包(其实就是创建文件夹)2️⃣
test.go
文件内容package Test func test() { //小写字母内部函数 println("hello world") } func Test() { //大写字母可以对外的函数 test() }
3️⃣ 使用
import
导入包后,调用package main import "var/Test" func main() { Test.Test() Test.test() //报错 }
对外暴露的函数和变量可以被包外的调用者导入和访问,如果是不对外暴露的话,那么仅包内的调用者可以访问,外部将无法导入和访问,该规则适用于整个Go语言,例如后续会学到的结构体及其字段,方法,自定义类型,接口等等
私有
⭐️
go
中约定,一个包内名为internal
包为私有包,其它的包将无法访问私有包中的任何东西。下面看一个例子1️⃣
interal.go
中文件如下package Test_internal func Internal() { println("我是内部包中的Test_internal包中的函数") }
2️⃣ 此时
internal
包是Test
的内部包,Test2
将无法访问3️⃣
var
包也不可以访问,对于var
包来说internal
包不是它的内部包运算符
⭐️ 和平常语言的运算符差不多
Precedence Operator 5 * / % << >> & &^ 4 + - | ^ 3 == != < <= > >= 2 && 1 ||
⭐️ 有一点需要稍微注意下,go语言中没有选择将
~
作为取反运算符,而是复用了^
符号,当两个数字使用^
时,例如a^b
,它就是异或运算符,只对一个数字使用时,例如^a
,那么它就是取反运算符。go也支持增强赋值运算符,如下a += 1 a /= 2 a &^= 2
⭐️
Go
没有虽然有自减运算符,但是它们被降级为statement
语句,而且运算符只能位于操作数的后面,且没有返回值!!!在编程语言中,"statement"(语句)是一个基本的概念,它指的是完成一个具体任务或操作的最小单位代码。语句是构成程序的基本构建块,用于向计算机发出指令,告诉它执行什么样的操作。根据不同的编程语言,语句的形式和功能会有所不同,但它们通常包括赋值、条件判断、循环控制、函数调用、表达式计算等
package main func main() { var a = 10 a-- //减减后为 9 println(a) println(a--) //错误没有,在go中自增自减都没有返回值 println(--a) //错误运算符要在操作数后 }
字面量
⭐️和
java/python
的差不多,按照计算机科学的术语来讲是用于表达源代码中一个固定值的符号,也叫字面值,顾名思义就是字面上的值
1️⃣整型字面量
为了便于阅读,允许使用下划线
_
来进行数字划分,但是仅允许在前缀符号之后和数字之间使用。十进制:无前缀,如 24
二进制:前缀 0b 或 0B,如 0b00(表示十进制的0)
八进制:前缀0o
或0O
,如0O24
(表示十进制的20)
十六进制:前缀0x
或 0X,如 0x00(表示十进制的0)24 // 24 024 // 24 2_4 // 24 0_2_4 // 24 10_000 // 10k 100_000 // 100k 0O24 // 20 0b00 // 0 0x00 // 0 0x0_0 // 0
2️⃣ 浮点数字面量
通过不同的前缀可以表达不同进制的浮点数
0. 72.40 072.40 // == 72.40 2.71828 1.e+0 6.67428e-11 1E6 .25 .12345E+5 1_5. // == 15.0 0.15e+0_2 // == 15.0 0x1p-2 // == 0.25 0x2.p10 // == 2048.0 0x1.Fp+0 // == 1.9375 0X.8p-0 // == 0.5 0X_1FFFP-16 // == 0.1249847412109375 0x15e-2 // == 0x15e - 2 (integer subtraction)
3️⃣ 复数字面量
0i 0123i // == 123i 0o123i // == 0o123 * 1i == 83i 0xabci // == 0xabc * 1i == 2748i 0.i 2.71828i 1.e+0i 6.67428e-11i 1E6i .25i .12345E+5i 0x1p-2i // == 0x1p-2 * 1i == 0.25i
4️⃣ 字符字面量
字符字面量必须使用单引号括起来
''
,Go中的字符完全兼容utf8
。'a' 'ä' '你' '\t' '\000' '\007' '\377' '\x07' '\xff' '\u12e4' '\U00101234'
5️⃣ 转义字符
Go中可用的转义字符
\a U+0007 响铃符号(建议调高音量) \b U+0008 回退符号 \f U+000C 换页符号 \n U+000A 换行符号 \r U+000D 回车符号 \t U+0009 横向制表符号 \v U+000B 纵向制表符号 \\ U+005C 反斜杠转义 \' U+0027 单引号转义 (该转义仅在字符内有效) \" U+0022 双引号转义 (该转义仅在字符串内有效)
6️⃣字符串字面量
字符串字面量必须使用双引号
""
括起来或者反引号(反引号字符串不允许转义)`abc` // "abc" `\n \n` // "\\n\n\\n" "\n" "\"" // `"` "Hello, world!\n" "今天天气不错" "日本語" "\u65e5本\U00008a9e" "\xff\u00FF"
风格
⭐️
go
官方提供了一个gofmt
用来格式化go
代码⭐️ 花括号必须和函数名要在同一行不能换行
⭐️ 花括号不能省略
⭐️ 运算符号的间隔:优先级高的运算符紧凑,低的则间隔明显