2016-02-13 192 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