2016-02-13 190 views
1

http://openmymind.net/Things-I-Wish-Someone-Had-Told-Me-About-Go/更改結構屬性值

試圖讓我的頭轉過去,仍然很新。我知道C中的參考和指針,我似乎無法在Go中工作。我已閱讀了許多有關此問題的文章,但仍然沒有真正理解和實施解決方案。

字符有健康和atk點。

Chars can Attack()。

Combat round calls這個角色可以攻擊的攻擊()。

意圖,當在字符上調用Attack()時,健康在另一個字符上發生變化。

當前運行狀況在字符中不會改變。

有人可以給我一個簡潔的例子,說明如何改變右側物體上的值嗎?

package main 

import (
    "fmt" 
    "math/rand" 
    "time" 
) 

//Character health + atk of 
type Character struct { 
    Health, Atk int 
} 

//Attack ... Character can Attack 
func (c *Character) Attack(health, atk int) { 
    health -= atk 
} 

//CharacterInterface ... methods for characters 
type CharacterInterface interface { 
    Attack(health, atk int) 
} 

func combatRound(p, e Character) { 
    whoAtks := rand.Intn(100) 
    if whoAtks > 30 { 
     p.Attack(e.Health, p.Atk) 
     fmt.Println(p.Health) 
    } else { 
     e.Attack(p.Health, e.Atk) 

     fmt.Println(p.Health) 
    } 
} 

func main() { 
    //seed rand generator for the current run 
    rand.Seed(time.Now().UTC().UnixNano()) 
    p := Character{20, 5} 
    e := Character{20, 5} 
    combatRound(p, e) 
    fmt.Println("Player Health: %d \n Enemy Health: %d", p.Health, e.Health) 

} 
+0

'func combatRound(ref p,ref e Character){'什麼是'ref'業務?它甚至編譯? – hobbs

+0

哦,這是我正在嘗試忘記改變的東西。對不起 已修復。 –

+1

你最好命名你的界面「攻擊者」,那麼任何具有「攻擊」功能的「角色」都可以滿足它。我認爲你甚至可以創建一個AttackTarget接口,然後Attack功能就會成爲target.TakeDamage(c.atk)。然後人物,物體,陷阱,盒子等,都可以單獨進行攻擊和攻擊。 –

回答

2

在Go中,對函數或方法的調用的參數和接收方總是按值傳遞(通過賦值)。

例如,

package main 

import (
    "fmt" 
    "math/rand" 
    "time" 
) 

type Attacker interface { 
    Attacks(a *Character) 
} 

type Character struct { 
    Health, Attack int 
} 

func (c *Character) Attacks(a *Character) { 
    a.Health -= c.Attack 
} 

func combatRound(player, enemy *Character) { 
    if rand.Intn(100) <= 30 { 
     player, enemy = enemy, player 
    } 
    player.Attacks(enemy) 
} 

func main() { 
    rand.Seed(time.Now().UnixNano()) 
    p := &Character{20, 5} 
    e := &Character{20, 5} 
    combatRound(p, e) 
    fmt.Printf("Player Health: %d\nEnemy Health: %d\n", p.Health, e.Health) 
} 

輸出:

$ go run attack.go 
Player Health: 20 
Enemy Health: 15 
$ go run attack.go 
Player Health: 20 
Enemy Health: 15 
$ go run attack.go 
Player Health: 15 
Enemy Health: 20 

The Go Programming Language Specification

Assignments

Assignment = ExpressionList assign_op ExpressionList . 

assign_op = [ add_op | mul_op ] "=" . 

每個左側操作數必須是可尋址的,映射索引 表達式或(for =僅指定賦值)空白標識符。操作數 可能會加上括號。

元組分配將多值 操作的各個元素分配給變量列表。有兩種形式。在第一個 中,右手操作數是單個多值表達式,如函數調用,通道或映射操作或類型斷言。 左側的操作數數量必須與 值的數量匹配。例如,如果f是返回兩個值的函數,則

x, y = f() 

將第一個值賦給x,將第二個賦值給y。在第二種形式 中,左側的操作數數量必須等於右側的 表達式的數量,每個表達式必須是單值的,右側的 第n個表達式將被分配給 上的第n個操作數左:

one, two, three = '一', '二', '三' 

該作業分兩個階段進行。首先,左邊的索引 表達式和指針間接(包括隱式指針 在選擇器中的間接尋址)操作數和右邊的表達式都按照通常的順序進行評估。其次,作業 按照從左到右的順序進行。

a, b = b, a // exchange a and b 

GO語句

player, enemy = enemy, player 

是一個元組分配的第二種形式。這是交換或交換兩種價值的慣用方式。在分配發生之前評估左邊的操作數和右邊的表達式。編譯器會爲您處理任何臨時變量。

combatRound功能,對於31個OT 100(區間[0,30]的[0,100))調用,平均而言,角色顛倒或互換,所述enemy(後衛)相斥的player(攻擊者) 。將指針交換到Characters反映了角色顛倒。玩家的健康狀況會下降,而不是敵人的健康。

+0

我看到你做了什麼,而且它更清晰直接。我看到現在發生了什麼,並且能夠修復我的代碼。你能否真正快速解釋一下 玩家,敵人=敵人,玩家是怎麼回事?這只是重新分配對象?沒有臨時變量?我沒跟隨,對不起。 通常換你看到這樣 變種臨時=敵人 敵人=玩家 球員=臨時 它的實際工作這種方式去?我在哪裏可以閱讀更多關於你在那裏做什麼? –

+1

@nathanrogers:對於'玩家,敵人=敵人,玩家',請參閱我修改後的答案。 – peterSO