数组&迭代&切片
二十一、数组
声明:var a = […] int/float 32/64 初始化:a := […] int = {1,2,3,4} 赋值:
package main
import "fmt"
func main() {
var a = [...] int {1,2,3,4}
a = [...] int {3,4,5,6}
for i:=0;i<len(a);i++ {
fmt.Printf("a[%d]: %d\n",i, a[i])
}
}
调用:var salary float32 = a[9]
二十二、迭代
package main
import (
"fmt"
)
func main(){
var a = [...] int {1,2,3,4,5,6}
for i,data := range a {
fmt.Printf("a[%d] = %d\n",i,data)
}
str := "hello wang "
for i,data := range str {
fmt.Printf("str[%d] = %c\n",i,data)
}
}结果:
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4
a[4] = 5
a[5] = 6
str[0] = h
str[1] = e
str[2] = l
str[3] = l
str[4] = o
str[5] =
str[6] = w
str[7] = a
str[8] = n
str[9] = g
str[10] =
(这个原本在指针后面但在这里因其与数组有关所以放在这里了) 三十六、Go 语言切片(Slice) Go 语言切片是对数组的抽象。
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
切片不需要说明长度。
你可以声明一个未指定大小的数组来定义切片: var identifier []type
或使用 make() 函数来创建切片: var slice1 []type = make([]type, len)
也可以简写为 slice1 := make([]type, len)
也可以指定容量,其中 capacity 为可选参数。 make([]T, length, capacity)
这里 len 是数组的长度并且也是切片的初始长度。
二十三、goto package main
import “fmt”
func main() { goto End fmt.Println(“giao”) End : fmt.Println(“wang”) //这就是goto } 二十四、实例:用递归函数求1~100的和
package main
import (
"fmt"
)
func wang01() (sum int) {
sum = wang02()
return sum
}
func wang02() (sum int) {
a := 0
Loop :
a++
sum += a
if a<100 {
goto Loop
}
return sum
}
func main() {
sum := 0
sum = wang01()
fmt.Println("sum(1~100) = ",sum)
}
运行的结果: sum(1~100) = 5050
进程 已完成,退出代码为 0
二十五、变量的实质就是占位符,用于引用计算机内存地址。 Go 语言的取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址。
package main
import "fmt"
func main() {
var a int = 10
fmt.Printf("变量的地址: %x\n", &a )
}
指针
二十六、指针 一个指针变量指向了一个值的内存地址。 一个指针变量指向了一个值的内存地址。 一个指针变量指向了一个值的内存地址。(重要的事说三遍)所以我用自动匹配类型%v的时候才自动输出了地址。
package main
import "fmt"
func main(){
var a *int
b := 12
a = &b
fmt.Printf("a~%v\n",a)
fmt.Printf("a~%v\n",*a)
}
输出的结果为: a~0xc00000a098 a~12
类似于变量和常量,在使用指针前你需要声明指针。指针声明格式如下:
var var_name var-type //var 就是变量的意思。 eg: var ip int / 指向整型/ var fp float32 / 指向浮点型 */ 本例中这是一个指向 int 和 float32 的指针。
二十七、如何使用指针 指针使用流程:
定义指针变量。 为指针变量赋值。 访问指针变量中指向地址的值。 在指针类型前面加上 * 号(前缀)来获取指针所指向的内容。
package main
import "fmt"
func main() {
var a int= 20
var ip *int
ip = &a
fmt.Printf("a 变量的地址是: %x\n", &a )
fmt.Printf("ip 变量储存的指针地址: %x\n", ip )
fmt.Printf("*ip 变量的值: %d\n", *ip )
}
以上实例执行输出结果为:
a 变量的地址是: 20818a220 ip 变量储存的指针地址: 20818a220 *ip 变量的值: 20
二十八、空指针判断:
if(ptr != nil) /* ptr 不是空指针 / if(ptr == nil) / ptr 是空指针 */
二十九、指针数组 有一种情况,我们可能需要保存数组,这样我们就需要使用到指针。
以下声明了整型指针数组: 格式: var ptr [3]*int; //这里的三是指元素的个数,“prt”就是数组名字了
例如:
package main
import "fmt"
const MAX int = 3
func main() {
a := []int{10,100,200}
var i int
var ptr [MAX]*int;
for i = 0; i < MAX; i++ {
ptr[i] = &a[i]
}
for i = 0; i < MAX; i++ {
fmt.Printf("a[%d] = %d\n", i,*ptr[i] )
}
}
以上代码执行输出结果为:
a[0] = 10 a[1] = 100 a[2] = 200 这是我自己写的一个例子:
package main
import (
"fmt"
"time"
)
func main() {
var a = [] int {1,2,3,4,5,6,7,8,9}
var ip *int
for i := 0;i<len(a);i++ {
ip = &a[i]
fmt.Printf("a[%d] = %d\n",i,*ip)
fmt.Printf("a[%d] = %d\n",i,ip)
time.Sleep(time.Second )
}
}输出结果为:
a[0] = 1
a[0] = 824633811344
a[1] = 2
a[1] = 824633811352
a[2] = 3
a[2] = 824633811360
a[3] = 4
a[3] = 824633811368
a[4] = 5
a[4] = 824633811376
a[5] = 6
a[5] = 824633811384
a[6] = 7
a[6] = 824633811392
a[7] = 8
a[7] = 824633811400
a[8] = 9
a[8] = 824633811408
进程 已完成,退出代码为 0
三十、绕口令:指向指针的指针
如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。
当定义一个指向指针的指针变量时,第一个指针存放第二个指针的地址,第二个指针存放变量的地址:
指向指针的指针变量声明格式如下:
var ptr **int;
以上指向指针的指针变量为整型。
访问指向指针的指针变量值需要使用两个 * 号,如下所示:
```go
package main
import "fmt"
func main() {
var a int
var ptr *int
var pptr **int //我认为命名规则很重要(ptr & pptr),方便去想
a = 3000
/* 指针 ptr 地址 */
ptr = &a
/* 指向指针 ptr 地址 */
pptr = &ptr
/* 获取 pptr 的值 */
fmt.Printf("变量 a = %d\n", a )
fmt.Printf("指针变量 *ptr = %d\n", *ptr )
fmt.Printf("指向指针的指针变量 **pptr = %d\n", **pptr)
}
以上实例执行输出结果为:
变量 a = 3000 指针变量 *ptr = 3000 指向指针的指针变量 **pptr = 3000
关于指向指针的指针变量,指针命名我发现一个更有规律的: prt prt2 prt3 …
三十一、在函数中使用指针
package main
import "fmt"
func swap(x *int, y *int) {
*x, *y = *y, *x
}
func main() {
var a int = 100
var b int= 200
swap(&a, &b)
fmt.Printf("交换后 a 的值 : %d\n", a )
fmt.Printf("交换后 b 的值 : %d\n", b )
}
输出结果: 交换后 a 的值 : 200 交换后 b 的值 : 100
进程 已完成,退出代码为 0
结构体
三十二、Go 语言结构体(包含多种类型的数据集合) Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。
结构体表示一项记录,比如保存图书馆的书籍记录,每本书有以下属性:
Title :标题 Author : 作者 Subject:学科 ID:书籍ID 定义结构体
实例:
package main
import "fmt"
type Books struct {
title string
author string
subject string
book_id int
}
func main() {
fmt.Println(Books{"Go 语言", "www.runoob.com", "Go 语言教程", 6495407})
fmt.Println(Books{title: "Go 语言", author: "www.runoob.com", subject: "Go 语言教程", book_id: 6495407})
fmt.Println(Books{title: "Go 语言", author: "www.runoob.com"})
}
输出结果为:
{Go 语言 www.runoob.com Go 语言教程 6495407} {Go 语言 www.runoob.com Go 语言教程 6495407} {Go 语言 www.runoob.com 0}
三十三、访问结构体成员 结构体类型变量使用 struct 关键字定义,实例如下:
实例:
package main
import "fmt"
type Books struct {
title string
author string
subject string
book_id int
}
func main() {
var Book1 Books
var Book2 Books
Book1.title = "Go 语言"
Book1.author = "www.runoob.com"
Book1.subject = "Go 语言教程"
Book1.book_id = 6495407
Book2.title = "Python 教程"
Book2.author = "www.runoob.com"
Book2.subject = "Python 语言教程"
Book2.book_id = 6495700
fmt.Printf( "Book 1 title : %s\n", Book1.title)
fmt.Printf( "Book 1 author : %s\n", Book1.author)
fmt.Printf( "Book 1 subject : %s\n", Book1.subject)
fmt.Printf( "Book 1 book_id : %d\n", Book1.book_id)
fmt.Printf( "Book 2 title : %s\n", Book2.title)
fmt.Printf( "Book 2 author : %s\n", Book2.author)
fmt.Printf( "Book 2 subject : %s\n", Book2.subject)
fmt.Printf( "Book 2 book_id : %d\n", Book2.book_id)
}
以上实例执行运行结果为:
Book 1 title : Go 语言 Book 1 author : www.runoob.com Book 1 subject : Go 语言教程 Book 1 book_id : 6495407 Book 2 title : Python 教程 Book 2 author : www.runoob.com Book 2 subject : Python 语言教程 Book 2 book_id : 6495700
三十四、结构体作为函数参数 你可以像其他数据类型一样将结构体类型作为参数传递给函数。并以以上实例的方式访问结构体变量:
实例
package main
import "fmt"
type Books struct {
title string
author string
subject string
book_id int
}
func main() {
var Book1 Books
var Book2 Books 将结构体类型理解为新的数据类型
Book1.title = "Go 语言"
Book1.author = "www.runoob.com"
Book1.subject = "Go 语言教程"
Book1.book_id = 6495407
Book2.title = "Python 教程"
Book2.author = "www.runoob.com"
Book2.subject = "Python 语言教程"
Book2.book_id = 6495700
printBook(Book1)
printBook(Book2)
}
func printBook( book Books ) {
fmt.Printf( "Book title : %s\n", book.title)
fmt.Printf( "Book author : %s\n", book.author)
fmt.Printf( "Book subject : %s\n", book.subject)
fmt.Printf( "Book book_id : %d\n", book.book_id)
}
以上实例执行运行结果为:
Book title : Go 语言 Book author : www.runoob.com Book subject : Go 语言教程 Book book_id : 6495407 Book title : Python 教程 Book author : www.runoob.com Book subject : Python 语言教程 Book book_id : 6495700
这是一个我自己写的程序:
package main
import "fmt"
type books struct {
title string
author string
book_id string
}
var i int
func main() {
var book1 books
var book2 books
book1.title = "wanglaoda"
book1.author = "wang"
book1.book_id = "giao"
book2.title = "Gwanglaoda"
book2.author = "Gwang"
book2.book_id = "Ggiao"
sb(book1)
fmt.Println("~~~~")
sb(book2)
fmt.Println("@@@@@")
}
func sb (book books) { 在此处可以把books理解为一个数据类型,book作为它的形参
i++
fmt.Printf("book%d.title=%v\n",i, book.title)
}
输出结果: book1.title=wanglaoda “~~~” book2.title=Gwanglaoda @@@@@
三十五、结构体指针 你可以定义指向结构体的指针类似于其他指针变量,格式如下:
var struct_pointer *Books
以上定义的指针变量可以存储结构体变量的地址。查看结构体变量地址,可以将 & 符号放置于结构体变量前:
struct_pointer = &Book1
使用结构体指针访问结构体成员,使用 “.” 操作符:
struct_pointer.title
|