Go语言是一种开源的编程语言,以其简洁、高效和并发特性而闻名,作为一个小白,如何从已知的语言出发去了解GO,并在此过程中体会GO语言的特点是我认为比较好的初学方式。笔记中,我将主要根据所学的多种(C/JAVA/Python)编程语言去了解GO语言。
(一)GO语言与C、Java、Python在基础语法上的异同
(1)定义变量
- C语言
int ages = 20;
char str[] = "Hello, World!";
- Java语言
int age = 20;
String str = "Hello, World!";
- python语言
age = 20 #当输入;将被自动忽略,如果编译器有代码规范的话,会标黄
str = "Hello, World!"
-GO语言
age := 20 //相对C/Java更加简洁
str := "Hello, World!"
其中GO语言的Hello, World!编码如下:
package main
import "fmt"
func main() {
str := "Hello, World!"
fmt.Println(str)
}
(2)条件语句
- C语言
if (age >= 18) {
printf("成年人");
} else {
printf("未成年人");
}
- Java语言
if (age >= 18) {
System.out.println("成年人");
} else {
System.out.println("未成年人");
}
- python语言
if age >= 18:
print("成年人")
else:
print("未成年人")
-GO语言
if age >= 18 {
fmt.Println("成年人")
} else {
fmt.Println("未成年人")
}
可以看出GO语言在条件语句上的if-else输出形式上并无太多不同,但是值得注意的是在GO语言中,switch语句有些许不同,如下:
package main
import "fmt"
func main() {
num := 2
switch num {
case 1:
fmt.Println("Num is equal to 1")
case 2:
fmt.Println("Num is equal to 2")
case 3:
fmt.Println("Num is equal to 3")
default:
fmt.Println("Num is not 1, 2, or 3")
}
}
注意以下几点:
- 每个
case后面不需要使用break语句来结束,Go语言中的switch语句默认会自动退出。 case后面的表达式必须是一个常量值(比如整数、字符、字符串),而不是一个变量。default块是可选的,用于处理除了case块之外的其他情况。
当然这只是switch语句的基本用法,还可以使用switch语句进行更复杂的判断,比如使用表达式或类型断言作为判断条件,以及使用fallthrough关键字来实现穿透效果。根据具体的需求,可以灵活运用switch语句来处理不同的情况。
(3)循环语句
- C语言:
for (int i = 0; i < 5; i++) { printf("%d ", i); } - Java语言:
for (int i = 0; i < 5; i++) { System.out.print(i + " "); } - Python语言:
for i in range(5): print(i, end=" ") - Go语言:
值得一提的是,Go语言中只有一种循环结构,即for i := 0; i < 5; i++ { fmt.Printf("%d ", i) }for循环,而其他三种语言具有多种循环结构(如C语言的for、while和do-while,Java语言的for、while和do-while,Python语言的for和while)。 而且在循环条件表达式上Go语言的for循环的条件部分不需要使用括号,而其他三种语言通常需要使用括号将条件表达式包裹起来。在C语言和Java语言中,循环变量的作用域限制在循环语句块内部;而在Go语言和Python语言中,循环变量的作用域扩展到整个循环体外部。
(4)数组
- C语言:
int arr1[5]; // 声明一个大小为5的整数数组 char arr2[] = {'a', 'b', 'c'}; // 声明并初始化一个含有3个字符的数组 - Java语言:
int[] arr1 = new int[5]; // 声明一个大小为5的整数数组 String[] arr2 = {"a", "b", "c"}; // 声明并初始化一个含有3个字符串的数组 - Python语言:
arr1 = [0] * 5 # 声明一个大小为5的整数数组,并初始化为0 arr2 = ["a", "b", "c"] # 声明并初始化一个含有3个字符串的数组 - Go语言:
var arr1 [5]int // 声明一个大小为5的整数数组 arr2 := [3]string{"a", "b", "c"} // 声明并初始化一个含有3个字符串的数组
需要注意的以下几点:
- 数组长度:Go语言中声明数组时,必须显式指定数组的长度,而其他三种语言中可以动态初始化数组或使用动态数组。
- 数组切片:Go语言引入了数组切片(slice)的概念,使得对数组的操作更加灵活。C语言、Java语言和Python语言没有直接对应的数组切片概念,需要使用其他数据结构来实现类似的功能。数组切片是一个引用类型,可以动态调整大小,并支持类似于动态数组的功能。
-
GO语言示例:
arr := []int{1, 2, 3, 4, 5} // 声明并初始化一个数组切片 arr = append(arr, 6) // 在数组切片末尾添加元素
- 数组传递方式:在函数调用中,Go语言中数组作为参数传递给函数时是按值传递的,而其他三种语言中数组作为参数传递时通常是按引用传递的.
- Go语言:
func modifyArray(arr [5]int) { arr[0] = 100 } arr := [5]int{1, 2, 3, 4, 5} modifyArray(arr) fmt.Println(arr) // 输出 [1 2 3 4 5] - Python语言:
def modify_array(arr): arr[0] = 100 arr = [1, 2, 3, 4, 5] modify_array(arr) print(arr[0]) # 输出 100
(5)函数定义
- C语言:
int add(int a, int b) { return a + b; } - Java语言:
public int add(int a, int b) { return a + b; } - Python语言:
def add(a, b): return a + b - Go语言:
func add(a, b int) int { return a + b
需要注意的是:
1. Go语言中的函数参数传递方式与其他三种语言略有不同。
- Go语言中的函数参数传递方式既可以是值传递,也可以是引用传递。当参数是基本类型时,采用值传递;当参数是引用类型(如指针、数组、切片、映射、通道)时,采用引用传递。
- C语言中的函数参数传递方式是按值传递,即传递参数的副本给函数。
- Java语言中的函数参数传递方式也是按值传递,但对于对象类型的参数,实际上是传递了对象的引用。
- Python语言中的函数参数传递方式是按对象引用传递。
2. Go语言与其他三种语言在返回值方面也存在一些区别。
- Go语言可以返回多个值,而其他三种语言通常只能返回一个值。这使得Go语言在一些情况下更加方便和灵活。
- C语言中可以通过指针参数来实现函数返回多个值的效果。
- Java语言和Python语言可以使用类或者对象封装多个返回值。
3. Go语言对于错误处理有着独特的设计。
- Go语言使用函数的多返回值机制来处理错误。通常,一个函数在遇到错误时会返回一个错误对象,调用者可以根据返回的错误对象来判断和处理错误。
- C语言通常使用函数的返回值来表示错误码,或者通过指针参数返回错误码。
- Java语言使用异常机制来处理错误,异常可以被捕获和处理,或者继续抛出。
- Python语言也使用异常机制来处理错误,异常可以被捕获和处理,或者继续抛出。
(二)GO语言常用特性解析
1. 包管理:
- Go使用包(package)来组织和管理代码。每个Go程序都必须有一个
main包,并在其中的main函数作为程序的入口点。
2. 变量和类型:
- 声明变量时,需要指定变量名和类型。Go具有基本类型(如整数、浮点数、布尔值)和复合类型(如数组、切片、映射)。
- 可以使用
var关键字声明变量,也可以使用短变量声明(:=)进行快速声明并初始化变量。
3. 控制结构:
- Go支持常见的控制结构,包括条件语句(
if/else)、循环语句(for)、选择语句(switch)和错误处理(defer/panic/recover)。
4. 函数和方法:
- 可以使用
func关键字定义函数。函数可以有多个参数和返回值。 - Go还支持面向对象编程范式,它提供了方法(method)的概念。方法是与特定类型关联的函数。
5. 并发和并行:
- Go内置了原生的并发支持,使用
go关键字可以创建并发执行的goroutine。可以使用通道(channel)在goroutine之间进行通信和同步。 - 此外,Go还提供了
sync包,用于更复杂的并发模式,如互斥锁和条件变量。
6. 错误处理:
- Go鼓励显式处理错误,以避免悬挂的goroutine和未处理的异常。常见的做法是使用多返回值,其中一个返回值是错误类型。
7. 运行时反射:
- Go提供了反射机制,使程序能够检查和修改变量的类型和值。这对于编写通用代码和处理未知类型非常有用。
8. 包和依赖管理:
- Go使用
go mod命令来管理包和依赖项。可以使用go get命令下载和安装外部包,使用import关键字引入包。
本人对GO语言的了解还不够,编写过程可能存在错误,希望各位批评指正。