本帖最后由 Elan 于 2026-6-28 10:55 编辑
Elan已经不想再学习R语言了,所以现在重开一个Go语言专栏,希望这次能坚持下去(doge)。
<( ̄︶ ̄)↗[GO!]
本文受众:希望学一门能快速学懂的高效编程语言、希望进行网络开发的同志们。
0.封装主程序、导入包
- package main
- import (
- "fmt"
- )
- func main() {
- // Write your solution here
- /* You can also comment like this
- */
- fmt.Println("HelloWorld")
- }
复制代码
如上,有编程基础的同志们大概可以理解,我们使用import来导入go中的包,fmt就是go中用来标准化输出的包,fmt.Println等价于python中的print,你还可以使用其中的:
- fmt.Print():用于将文本打印到控制台。
- fmt.Printf():用于格式化文本并将其打印到控制台。
当然,该项目只引用了单个包,我们还可以这样写:
注释的方式有些类似js,不多赘述。
我们package了main(主程序),类似python,如果你是在编写一个包而非主程序,按照惯例,包名与导入路径的最后一个元素相同。例如,"math/rand" 包包含以 package rand 语句开头的文件。
眼尖的同志们会发现Println的首字母是大写的,这是因为在 Go 语言中,如果名称以大写字母开头,则该名称是导出的。例如,Pizza 是一个导出名称,Pi 也是,它从 math 包中导出。pizza 和 pi 不以大写字母开头,因此它们不是导出的,只能作用在它所编写的域中(有点类似私有)。在导入包时,您只能引用其导出名称。任何“未导出”的名称在包外是无法访问的。
不同于某些语言,你在书写行间代码时不必加上分号。但是行内代码需要。
- [√]
- fmt.Print('a')
- fmt.Print('b')
- ---
- [√]
- fmt.Print('a');
- fmt.Print('b');
- ---
- [√]
- fmt.Print('a');fmt.Print('b')
- ---
- [×]
- fmt.Print('a') fmt.Print('b')
复制代码
在线运行工具:Go 在线工具 | 菜鸟工具
1.函数
相比于python,Go的函数更为复杂。
- package main
- import "fmt"
- func add(x int, y int) int {
- return x + y
- }
- func main() {
- fmt.Println(add(42, 13))
- }
复制代码 我们使用func来定义函数(在定义主程序入口的时候也是这样的)。函数可以接受0个或者若干个变量,写在函数名后括号内,变量名后面需要空格来声明类型。
但是连续类型变量出现的时候可以使用函数续,比如上方代码add的输入都是整型int,我们可以写成这样:
- func add(x, y int) int {
- return x + y
- }
复制代码 在函数内容开始之前需要设置函数的返回类型(可以不返回),如上方 `) int {`。
如果函数需要返回多种类型的量,需要在括号内分别说明:
- func swap(x, y string) (string, string) {
- return y, x
- }
复制代码 顺带一提,Go中声明变量类似js,先设置变量名再设置类型,注意上文提到的开头大小写区别!
- var a string = "HelloWorld"
- var b, c int = 1, 2
复制代码 第二行也是使用了函数续,也和python类似,Go可以同时声明并赋值多个变量,即多重赋值。所以Go也支持对变量(类型相同或者支持隐式转换者)进行交换:
与众不同的是,Go可以在声明的同时赋值(短赋值)。需要注意的是,var声明的变量可以在函数外部,这样函数里仍然可以调用。但是短赋值不能在函数外部,因为Go要求函数外部的代码必须以关键字开头。
需要注意的是,`:=`的左侧可以是已经声明过的变量:
但是不能全是已经声明过的变量:
我们回到函数来。Go的返回值是可以命名的(具名返回),如果这样,它们被视为在函数顶部定义的变量,所以在函数内部不需要再声明。这些名称应用于记录返回值的含义。不带参数的 return 语句会返回命名的返回值。这被称为“裸”返回。
- package main
- import "fmt"
- func split(sum int) (x, y int) {
- x = sum * 4 / 9
- y = sum - x
- return
- }
- func main() {
- fmt.Println(split(32))
- }
复制代码 在这个例子里,split函数接受sum,并且定义了两个返回量x和y,指定它们的类型为int,相当于:
函数对x和y操作后,使用return方法裸返回,那么会检索头部要求返回的量,即返回x和y的量,所以显示`14 18`。
2.基本类型(节选自JetBrains Academy)
- package main
- import (
- "fmt"
- "math/cmplx"
- )
- var (
- ToBe bool = false
- MaxInt uint64 = 1<<64 - 1
- z complex128 = cmplx.Sqrt(-5 + 12i)
- )
- func main() {
- fmt.Printf("Type: %T Value: %v\n", ToBe, ToBe)
- fmt.Printf("Type: %T Value: %v\n", MaxInt, MaxInt)
- fmt.Printf("Type: %T Value: %v\n", z, z)
- }
复制代码
Go 的基本类型有 - bool
- string
- int int8 int16 int32 int64
- uint uint8 uint16 uint32 uint64 uintptr
- byte // uint8 的别名
- rune // int32 的别名 // 表示一个 Unicode 代码点
- float32 float64
- complex64 complex128
复制代码
示例展示了几种类型的变量, 还展示了变量声明可以像 import 语句一样被“分组”到块中(可以使用制表符来达到美观效果,是Go独有的神奇之物)。 在 32 位系统中,int、uint 和 uintptr 类型通常是 32 位宽,而在 64 位系统中是 64 位宽。 当你需要一个整数值时,应该使用 int,除非你有特定理由使用定长或无符号整数类型。 上述示例还使用了格式化输出(Printf),这里是详细的介绍:
- 通用动词(适用于所有类型)
- %v 默认格式,最常用
- %+v 结构体时带字段名
- %#v 输出Go语法表示(字面量)
- %T 输出值的类型
- %% 输出百分号%
- 整数类型(int/uint等)
- %b 二进制
- %c 对应的Unicode字符
- %d 十进制
- %+d 带正负号的十进制
- %o 八进制(无前缀)
- %O 八进制,带0o前缀
- %q 单引号包裹的字符字面量
- %x 十六进制(小写字母)
- %X 十六进制(大写字母)
- %#x 十六进制,带0x前缀
- %#X 十六进制,带0X前缀
- %U Unicode格式,如U+1234
- 浮点数和复数
- %b 二进制指数形式(科学计数法)
- %e 科学计数法(e指数)
- %E 科学计数法(E指数)
- %f 十进制小数
- %F %f的同义词
- %g 自动选择%e或%f(更紧凑)
- %G 自动选择%E或%F
- %x 十六进制表示(小写)
- %X 十六进制表示(大写)
- 字符串和字节切片
- %s 普通字符串
- %q 双引号包裹的字符串(转义)
- %x 十六进制(小写,无空格)
- %X 十六进制(大写,无空格)
- % x 十六进制,字节间带空格
- 布尔类型
- %t true或false
- 指针
- %p 十六进制地址,带0x前缀
- 宽度和精度控制(可插入%和动词之间)
- 宽度(最小字符数):
- %5d 右对齐,宽度5
- %-5d 左对齐,宽度5
- %05d 右对齐,宽度5,用0填充
- 精度(浮点数小数位数):
- %.2f 保留2位小数
- %6.2f 总宽6,保留2位小数
- 其他实用提示
- %p 也可打印切片、map等引用类型的地址
- %q 用于整数时输出单引号字符字面量
复制代码 当然为了偷懒我们可以都用`%v`。了解完格式化输出后我们回到类型的学习上来。在量赋值时如果没有给值(未显式初始化)就会被给上该类型的零值。
- 零值为:
- 数值类型为0,
- 布尔类型为false,
- 字符串类型为""(空字符串)。
复制代码 我们有时需要转换类型,比如a是整型的1,我想把a的值赋给浮点型的b,就需要转换。
表达式 T(v) 将值 v 转换为类型 T。 一些数值转换示例: - var i int = 42
- var f float64 = float64(i)
- var u uint = uint(f)
复制代码或者,更简单的写法: - i := 42
- f := float64(i)
- u := uint(f)
复制代码与 C 不同,在 Go 中,不同类型的项目之间赋值需要显式转换。 另外,当声明一个变量而不指定显式类型时(可以使用:=语法或者var =表达式语法),变量的类型由右侧的值推断而来。
当声明的右侧具有类型时,新变量与其具有相同的类型:
- var i int
- j := i // j 是一个 int
复制代码 但是当右侧包含一个无类型的数值常量时,新变量可能是int、float64或complex128,这取决于常量的精度:
- i := 42 // int
- f := 3.142 // float64
- g := 0.867 + 0.5i // complex128
复制代码
|