iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0
自我挑戰組

挑戰typescript+react+golang+graphql系列 第 3

Day3 Go Struct/Array/Slice

  • 分享至 

  • xImage
  •  

Struct

Go內常使用struct來自定型別

package main

import "fmt"

type Person struct {
	name string
}
func main() {
    // 這邊是創建一個變數p1並賦值給p1
	p1 := &Person{name: "Sam"}
	fmt.Printf("Name is %v \n", p1.name)
    // Name is Sam
}

Go 一般的方法宣告是
func方法名稱(接收參數 型別)(回傳型別 如果不需回傳型別可以省略)

還有另一種方法叫receiver 長這樣:
func(變數名稱 型別)方法名稱(接收參數 型別)(回傳型別 如果不需回傳型別可以省略)
一樣用程式示範比較好懂

package main

import "fmt"

type Person struct {
	name string
}

func (p *Person) setNameWithPointer(newName string) {
	p.name = newName
}

func (p Person) setName(newName string) {
	p.name = newName
}

func main() {
	p1 := &Person{name: "Sam"}
	fmt.Printf("Name is %v \n", p1.name)
    //Name is Sam

	p1.setName("Alex")
	fmt.Printf("Name is %v \n", p1.name)


	p1.setNameWithPointer("Ann")
	fmt.Printf("Name is %v \n", p1.name)

    
}

我寫了兩個receiver function setNameWithPointer&setName
大家可以猜猜看哪一個才可以成功更改p1.name

p1 := &Person{name: "Sam"}
	fmt.Printf("Name is %v \n", p1.name)
    //Name is Sam

	p1.setName("Alex")
	fmt.Printf("Name is %v \n", p1.name)
    //Name is Sam

	p1.setNameWithPointer("Ann")
	fmt.Printf("Name is %v \n", p1.name)
    //Name is Ann 

答案是setNameWithPointer

struct也可以嵌入另一個struct,示範如下

package main

import "fmt"

type Person struct {
	name string
	job  Job
}

type Job struct {
	title  string
	salary int
}

func main() {
	
	// 也可以這樣實例化struct
	var p1 = new(Person)
	p1.name = "Sam"
	p1.job.title = "Software Engineer"
	p1.job.salary = 28000
	fmt.Printf("%v is a %v whose salary is %v \n", p1.name, p1.job.title, p1.job.salary)
    // Sam is a Software Engineer whose salary is 28000 
}

Array

Golang內的array跟其他程式語言的array是一樣的
不過因為array長度是固定的,使用上比較不靈活,所以比較少使用

package main

import "fmt"

func main() {

    // 宣告變數(沒初始值)
	var arr [5]int
	for i := range arr {
		fmt.Println(arr[i])
		// 0 0 0 0 0 沒有初始值,所以都是0
	}
    
    // 宣告變數(有初始值)
	var arr2 = [5]int{1, 2, 3, 4, 5}
	for i := range arr2 {
		fmt.Println(arr2[i])
		// 1 2 3 4 5 有設定初始值所以印出來不是0
	}

}

Slice

可以把它理解為可以動態新增長度的array
slice會依照slice的length自動擴展capacity

我們可以用make來宣告
make([]T, length, capacity)

package main

import "fmt"

func main() {
    
    
	// var s1 []int = make([]int, 0, 0) = var s1 []int
	var s1 []int = make([]int, 0, 0)
	fmt.Printf("s1 = %v, len = %v,cap = %v \n", s1, len(s1), cap(s1))
    // s1 = [], len = 0,cap = 0 

	// 	加入超過初始長度的值
	s1 = append(s1, 1)
	fmt.Printf("s1 = %v, len = %v,cap = %v \n", s1, len(s1), cap(s1))
    // s1 = [1], len = 1,cap = 1
    
	// 	也可以這樣宣告
	var s2 = []int{1, 2}
	fmt.Printf("s2 = %v, len = %v,cap = %v \n", s2, len(s2), cap(s2))
    // s2 = [1 2], len = 2,cap = 2
    
	// 	加入超過初始長度的值
	s2 = append(s2, 3, 4, 5)
	fmt.Printf("s2 = %v, len = %v,cap = %v \n", s2, len(s2), cap(s2))
    // s2 = [1 2 3 4 5], len = 5,cap = 6 
    
	// 複製s2的內容到s3
	var s3 = make([]int, len(s2), cap(s2))
	copy(s3, s2)
	fmt.Printf("s3 = %v, len = %v,cap = %v \n", s3, len(s3), cap(s3))
    // s2 = [1 2 3 4 5], len = 5,cap = 6 
    
	// slice新增跟刪除都是用append
	// s3[:1]意思是在s3這個slice內index 1之前的數不含index 1
	// s3[2:]意思是在s3這個slice內index 2之後的數
	s3 = append(s3[:1], s3[2:]...)
	fmt.Printf("s3 = %v, len = %v,cap = %v \n", s3, len(s3), cap(s3))
    // s3 = [1 3 4 5], len = 4,cap = 6 
}

上一篇
Day2.開發環境設定+Go語言基礎
下一篇
Day4. Map,list
系列文
挑戰typescript+react+golang+graphql18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言