GO语言基础语法:
Go标识符:
标识符用来命名变量,类型等程序实体。一个标识符实际上就是一个或是多个字母数字下划线组成的序列,但是第一个字符必须是字母或下划线而不是数字。
以下是有效的标识符:
mahesh kumar abc move_name a_123 myname50 _temp j a23b9 retVal
字符串的连接
package main
import "fmt"
func main() {
fmt.Println("Google" + "Runoob")
}
Go语言中的空格
在 Go 语言中,空格通常用于分隔标识符、关键字、运算符和表达式,以提高代码的可读性。
Go 语言中变量的声明必须使用空格隔开,如:
var x int
const Pi float64 = 3.14159265358979323846
在运算符和操作数之间要使用空格能让程序更易阅读:
无空格:
fruit=apples+oranges;
在变量与运算符间加入空格,程序看起来更加美观,如:
fruit = apples + oranges;
在关键字和表达式之间要使用空格。
例如:
if x > 0 {
// do something
}
在函数调用时,函数名和左边等号之间要使用空格,参数之间也要使用空格。
例如:
result := add(2, 3)
格式化字符串
Go 语言中使用 fmt.Sprintf 或 fmt.Printf 格式化字符串并赋值给新串:
- Sprintf 根据格式化参数生成格式化的字符串并返回该字符串。
- Printf 根据格式化参数生成格式化的字符串并写入标准输出。
GO语言中的打印方法
在Go语言中,你可以使用标准库中的fmt
包提供的函数来进行打印操作。fmt
包提供了多个函数用于不同类型的打印输出,常用的函数包括:
fmt.Print
:打印输出不带换行符。fmt.Println
:打印输出并换行。fmt.Printf
:根据格式化字符串进行打印输出。
以下是这些函数的示例用法:
package main
import "fmt"
func main() {
name := "Alice"
age := 25
fmt.Print("Hello, ") // 输出: Hello,
fmt.Print(name) // 输出: Alice
fmt.Print(", your age is ") // 输出: , your age is
fmt.Print(age) // 输出: 25
fmt.Println(" years old") // 输出: years old
fmt.Printf("Hello, %s! You are %d years old.\n", name, age) // 输出: Hello, Alice! You are 25 years old.
}
在上述代码中,我们使用了fmt.Print
、fmt.Println
和fmt.Printf
函数来打印输出不同的信息。fmt.Printf
函数使用了格式化字符串,其中的%s
和%d
分别表示字符串和整数的占位符,通过后面的参数依次填充。
除了这些基本的打印函数之外,fmt
包还提供了其他一些函数,例如fmt.Sprintf
用于将格式化的字符串保存到变量中,fmt.Errorf
用于创建格式化的错误信息等。
希望这个示例能够帮助你理解如何在Go语言中进行打印操作。
GO中声明变量的方法:
在Go语言中,const
和var
都用于声明变量,但它们之间有一些重要的区别。
- 常量(
const
):
const
用于声明常量,即在程序运行期间不会改变的值。- 声明常量时,必须在声明语句中为其赋予一个初始值,并且该值必须是一个可以在编译时确定的常量表达式。
- 声明的常量不能使用
:=
的简短变量声明语法。 - 常量的命名规则与变量相同,一般使用大写字母和下划线来表示。
- 常量的值在声明后不能修改。
示例:
const pi = 3.14
const (
monday = 1
tuesday = 2
wednesday = 3
)
- 变量(
var
):
var
用于声明变量,即在程序运行期间可以改变的值。- 声明变量时,可以选择显式指定变量的类型,也可以使用类型推断自动推断变量的类型。
- 声明变量时,可以通过赋值语句为其赋初值,也可以在后续的代码中进行赋值。
- 声明的变量可以使用
:=
的简短变量声明语法。
示例:
var age int
var name string = "John"
var height = 180 // 自动推断为int类型
score := 90 // 简短变量声明,自动推断为int类型
总结来说,const
用于声明常量,其值在编译时确定且不能修改。而var
用于声明变量,其值可以在程序运行期间改变。
在Go语言中,有多种方法可以声明变量。以下是常见的几种方式:
- 使用var关键字声明变量:可以使用
var
关键字声明一个或多个变量。语法为:var 变量名 类型
。例如:
var age int
var name string
- 使用短变量声明:可以使用短变量声明来声明并初始化变量。语法为:
变量名 := 值
。Go语言会根据值的类型推断变量的类型。例如:
age := 25
name := "John"
- 指定初始值的变量声明:可以在声明变量时直接指定初始值。语法为:
var 变量名 类型 = 值
。例如:
var age int = 25
var name string = "John"
- 声明多个变量:可以同时声明多个变量,每个变量都有自己的类型和初始值(可选)。语法为:
var ( 变量1 类型1 = 值1 变量2 类型2 = 值2 ... )
。例如:
var (
age int = 25
name string = "John"
salary float64
)
- 使用类型推断:在变量声明时,如果没有显式指定类型并且提供了初始值,Go语言会根据初始值的类型推断变量的类型。例如:
var age = 25
var name = "John"
这些是常见的变量声明方法,你可以根据具体的情况选择适合的方式来声明变量。
GO语言数据类型
在Go编程语言中,数据类型用于声明函数和变量
数据类型的出现是为了把数据分析成所需内存大小不同的数据,充分利用内存
布尔值:true false
数字类型:int float32 float64 Go
字符串类型
派生类型:指针类型 数组类型 结构化类型 channel类型 函数类型 切片类型 接口类型 Map类型
数字类型:int uint uintptr
浮点类型 float32 float64 complex64 complex128
GO语言函数调用中传递参数的两种方式:
当在函数调用中传递参数时,可以使用值传递或引用传递两种方式。
- 值传递(传递参数副本):
- 在值传递中,函数接收的是参数的副本,而不是原始参数本身。
- 当函数对参数进行修改时,只会修改参数的副本,不会影响原始参数。
- 值传递适用于传递简单的数据类型(如整数、浮点数、布尔值等)或结构体等较小的数据类型。
示例代码:
func updateValue(num int) {
num = 100
}
func main() {
value := 10
updateValue(value)
fmt.Println(value) // 输出:10
}
在上述代码中,updateValue
函数接收一个整数参数num
,并将其值修改为100。但在main
函数中调用updateValue
函数后,打印value
的值仍然是原始的值10,因为函数接收的是value
的副本,对副本的修改不会影响原始的值。
- 引用传递(传递参数指针):
- 在引用传递中,函数接收的是参数的地址(指针),而不是参数的副本。
- 通过传递指针,函数可以直接访问和修改原始参数的值。
- 引用传递适用于传递较大的数据类型(如切片、映射、结构体等)或需要修改原始参数的情况。
示例代码:
func updateValue(num *int) {
*num = 100
}
func main() {
value := 10
updateValue(&value)
fmt.Println(value) // 输出:100
}
在上述代码中,updateValue
函数接收一个整数指针参数num
,通过解引用指针并修改其指向的值,将value
的值修改为100。在main
函数中调用updateValue
函数后,打印value
的值变为100,因为传递给updateValue
函数的是value
的地址,函数可以直接修改原始的值。
需要注意的是,在使用引用传递时,需要确保传递给函数的是指针而不是值。这样函数才能修改原始参数的值。同时,还需要注意指针的生命周期,确保在函数结束后不再使用指向已释放内存的指针。
一个文件中只能有一个main函数,当作一个项目中只有一个main()函数。
GO语言中的指针(指针就是指向内存地址)
在Go语言中,指针是一种特殊的变量类型,用于存储变量的内存地址。通过指针,可以直接访问和修改内存中的数据。
要声明一个指针变量,可以使用*
符号在变量类型前面进行声明。例如,*int
表示一个指向整数类型的指针。
以下是一些关于指针的重要概念和操作:
- 取地址操作符(&):使用
&
符号可以获取变量的内存地址。
num := 10
ptr := &num
在上述代码中,&num
表示获取变量num
的内存地址,并将其赋值给指针变量ptr
。
- 解引用操作符(*):使用
*
符号可以访问指针指向的内存地址中存储的值。
num := 10
ptr := &num
value := *ptr
在上述代码中,*ptr
表示解引用指针ptr
,获取其指向的内存地址中存储的值,并将其赋值给变量value
。
- 创建指针:可以使用
new
函数来动态地创建指针,它会分配内存并返回指向该内存地址的指针。
ptr := new(int)
在上述代码中,new(int)
表示创建一个指向整数类型的指针,并将其赋值给指针变量ptr
。
- 传递指针:通过将指针作为参数传递给函数,可以实现引用传递,使函数能够修改原始参数的值。
func updateValue(ptr *int) {
*ptr = 100
}
num := 10
updateValue(&num)
在上述代码中,updateValue
函数接收一个整数指针参数ptr
,通过解引用指针并修改其指向的值,将num
的值修改为100。通过在函数调用时传递&num
,实现了对原始参数的修改。
指针在Go语言中常用于以下情况:
- 通过引用传递修改函数外部的变量。
- 动态分配内存,创建和操作复杂的数据结构,如切片和映射。
- 提高性能,避免复制大量数据。
需要注意的是,在使用指针时,需要确保指针指向的内存地址是有效的,避免空指针引用和悬垂指针的问题。
当涉及到使用指针时,以下是一些代码片段,可以帮助你更好地理解Go语言中指针的作用:
- 通过指针修改函数外部的变量:
func updateValue(ptr *int) {
*ptr = 100
}
func main() {
num := 10
fmt.Println("Before:", num) // 输出:Before: 10
updateValue(&num)
fmt.Println("After:", num) // 输出:After: 100
}
在上述代码中,通过将指向num
的指针传递给updateValue
函数,函数可以直接修改num
的值,使其从10变为100。
- 动态分配内存并使用指针操作数据结构:
type Person struct {
Name string
Age int
}
func main() {
ptr := new(Person)
ptr.Name = "John"
ptr.Age = 25
fmt.Println(ptr) // 输出:&{John 25}
}
在上述代码中,使用new
函数动态分配了一个Person
结构体的内存,并将其地址赋值给指针ptr
。然后,可以通过指针ptr
来访问和修改Person
结构体的字段。
- 交换两个变量的值:
func swap(a, b *int) {
temp := *a
*a = *b
*b = temp
}
func main() {
x, y := 10, 20
fmt.Println("Before swap:", x, y) // 输出:Before swap: 10 20
swap(&x, &y)
fmt.Println("After swap:", x, y) // 输出:After swap: 20 10
}
在上述代码中,通过传递两个整数的指针给swap
函数,函数可以交换两个变量的值。通过解引用指针并交换其指向的值,实现了变量值的交换。
这些代码片段展示了指针在Go语言中的应用场景,包括修改函数外部的变量、动态分配内存以及交换变量值等。通过理解和实践这些示例,你可以更好地掌握Go语言中指针的使用。
* & 这两个符号在指针中的作用
当涉及到指针时,*
和&
这两个符号具有不同的作用。
*
符号(解引用操作符):
- 在声明变量时,
*
用于指定一个变量是指针类型。例如,*int
表示一个指向整数的指针类型。 - 在使用指针时,
*
用于解引用指针,访问指针所指向的内存地址中存储的值。
通俗地说,可以将*
理解为“取出”或“访问”指针指向的值的操作符。
&
符号(取地址操作符):
- 在声明变量时,
&
用于获取变量的内存地址。 - 在使用指针时,
&
用于获取变量的地址,并将地址赋值给指针变量。
通俗地说,可以将&
理解为“获取”或“取得”变量的内存地址的操作符。
举例来说,假设有一个整数变量num
,我们可以使用&
来获取它的内存地址,并将地址存储在指针变量中:
num := 10
ptr := &num
在上述代码中,&num
表示获取变量num
的内存地址,并将其赋值给指针变量ptr
。此时,ptr
就指向了num
的内存地址。
而使用*
操作符,我们可以解引用指针并访问其指向的值:
value := *ptr
在上述代码中,*ptr
表示解引用指针ptr
,获取其指向的内存地址中存储的值,并将其赋值给变量value
。
总结起来,*
用于指定指针类型和解引用操作,而&
用于获取变量的内存地址。这两个符号在指针中的作用是为了方便地操作和访问内存中的数据。
GO中的循环语句
在Go语言中,有三种主要的循环语句:for
循环、while
循环和do-while
循环。
for
循环:for
循环是Go语言中最常用的循环语句,它的语法如下:
for 初始化语句; 循环条件; 循环后操作 {
// 循环体代码
}
初始化语句
用于初始化循环变量,循环条件
是一个布尔表达式,当条件为真时循环继续执行,循环后操作
用于更新循环变量的值。循环体代码会重复执行,直到循环条件为假时才会退出循环。
以下是一个示例,展示了使用for
循环输出数字1到5的例子:
package main
import "fmt"
func main() {
for i := 1; i <= 5; i++ {
fmt.Println(i)
}
}
输出结果为:
1
2
3
4
5
while
循环:Go语言中没有专门的while
关键字,但可以使用for
循环来实现类似的功能。可以省略初始化语句和循环后操作,只保留循环条件,形成一个无限循环,如下所示:
for 循环条件 {
// 循环体代码
}
以下是一个示例,展示了使用for
循环实现while
循环输出数字1到5的例子:
package main
import "fmt"
func main() {
i := 1
for i <= 5 {
fmt.Println(i)
i++
}
}
输出结果与前面的示例相同。
do-while
循环:Go语言中也没有专门的do-while
关键字,但可以使用for
循环和break
语句来实现类似的功能。先执行一次循环体代码,然后在循环条件判断之前使用break
语句来控制循环是否继续执行,如下所示:
for {
// 循环体代码
if !循环条件 {
break
}
}
以下是一个示例,展示了使用for
循环和break
语句实现do-while
循环输出数字1到5的例子:
package main
import "fmt"
func main() {
i := 1
for {
fmt.Println(i)
i++
if i > 5 {
break
}
}
}
输出结果与前面的示例相同。
没错,range
循环是Go语言中用于遍历可迭代数据结构的一种方便的方式。它可以用于遍历数组、切片、字符串、映射(map)等类型的数据。
range
循环的语法如下:
for 索引, 值 := range 可迭代数据结构 {
// 循环体代码
}
在每次循环迭代中,range
循环会将可迭代数据结构中的索引和对应的值分别赋值给指定的变量。然后,你可以在循环体中使用这些变量进行操作。
以下是一些示例,展示了如何使用range
循环遍历不同类型的数据结构:
遍历数组或切片:
package main
import "fmt"
func main() {
numbers := []int{1, 2, 3, 4, 5}
for index, value := range numbers {
fmt.Println(index, value)
}
}
输出结果为:
0 1
1 2
2 3
3 4
4 5
遍历字符串:
package main
import "fmt"
func main() {
message := "Hello, Go!"
for index, value := range message {
fmt.Println(index, string(value))
}
}
输出结果为:
0 H
1 e
2 l
3 l
4 o
5 ,
6
7 G
8 o
9 !
遍历映射(map):
package main
import "fmt"
func main() {
person := map[string]int{
"Alice": 25,
"Bob": 30,
"John": 35,
}
for key, value := range person {
fmt.Println(key, value)
}
}
输出结果为:
Alice 25
Bob 30
John 35
通过使用range
循环,你可以方便地遍历不同类型的可迭代数据结构,并同时获取索引和对应的值。希望这个示例能帮助你理解range
循环的用法。如果你有任何其他问题,请随时提问。
GO中的数组
当涉及到处理一组相同类型的数据时,Go语言中的数组(Array)是一种常用的数据结构。数组是一个固定长度的数据容器,它可以存储多个相同类型的元素。
在Go语言中,数组的声明方式如下:
var arr [n]T
其中,n
表示数组的长度,T
表示数组存储的元素类型。例如,声明一个包含5个整数的数组:
var arr [5]int
数组的索引从0开始,因此可以通过索引来访问数组中的元素。例如,给数组的第一个元素赋值为10:
arr[0] = 10
可以使用索引来访问数组中的元素,例如:
fmt.Println(arr[0]) // 输出数组的第一个元素
数组的长度是固定的,一旦声明后就不能再改变。如果需要存储更多的元素,需要声明一个更大长度的新数组,然后将原数组中的元素拷贝到新数组中。
可以使用len()
函数获取数组的长度,例如:
fmt.Println(len(arr)) // 输出数组的长度
Go语言还提供了一种简化数组声明和初始化的方式,称为数组字面量。使用数组字面量可以在声明数组的同时初始化数组的元素。例如,声明一个包含3个整数的数组并初始化为[1, 2, 3]
:
arr := [3]int{1, 2, 3}
如果省略数组的长度,Go语言会根据初始化的元素个数自动推断数组的长度。例如,声明一个包含3个整数的数组并初始化为[1, 2, 3]
:
arr := [...]int{1, 2, 3}
可以使用循环结构来遍历数组中的元素,例如:
for i := 0; i < len(arr); i++ {
fmt.Println(arr[i])
}
另外,Go语言还提供了切片(Slice)这个更灵活的数据结构,可以动态地调整大小。切片是基于数组的抽象,它提供了更多的操作和功能。因此,在实际开发中,切片比数组更常用。
数组中的切片
当涉及到处理动态大小的数据集合时,切片(Slice)是Go语言中更常用的数据结构。切片是基于数组的抽象,它提供了更多的操作和功能,使得处理数据集合更加灵活和方便。
切片是一个引用类型,它包含了一个指向底层数组的指针、切片的长度和切片的容量。
在Go语言中,切片的声明方式如下:
var slice []T
其中,T
表示切片中元素的类型。例如,声明一个包含整数的切片:
var slice []int
切片的长度是指切片中实际存储的元素个数,可以使用len()
函数获取切片的长度。切片的容量是指底层数组从切片的起始位置到底层数组的末尾位置的元素个数,可以使用cap()
函数获取切片的容量。
切片可以通过两种方式进行初始化。
第一种方式是使用切片字面量,类似于数组字面量的方式。例如,声明一个包含整数的切片并初始化为[1, 2, 3]
:
slice := []int{1, 2, 3}
第二种方式是通过对已有的数组或切片进行切片操作来创建一个新的切片。切片操作使用[start:end]
的语法,表示从索引start
到索引end-1
的元素范围。例如,从一个数组中创建一个切片:
arr := [5]int{1, 2, 3, 4, 5}
slice := arr[1:4] // 创建一个包含arr[1]、arr[2]、arr[3]的切片
切片是引用类型,当多个切片指向同一个底层数组时,它们共享相同的数据。修改其中一个切片的元素会影响到其他切片。
切片提供了一些常用的操作和方法,例如:
- 使用
append()
函数向切片中追加元素。 - 使用
copy()
函数将一个切片的元素复制到另一个切片。 - 使用切片的索引来访问和修改切片中的元素。
- 使用
len()
函数获取切片的长度。实际长度 - 使用
cap()
函数获取切片的容量。底层数组中从索引1到索引4
切片在Go语言中广泛应用于处理动态数据集合,它的灵活性和便利性使得开发人员能够更加方便地操作和处理数据。