为了账号安全,请及时绑定邮箱和手机立即绑定

去改变结构属性值

去改变结构属性值

Go
小怪兽爱吃肉 2021-12-13 18:19:23
http://openmymind.net/Things-I-Wish-Someone-Had-Told-Me-About-Go/试图让我的头脑围绕 Go,仍然很新。我知道 C 中的引用和指针,但我似乎无法在 Go 中使用它。我已经阅读了许多关于这个问题的文章,但仍然没有真正理解和实施解决方案。角色有健康和攻击点。字符可以 Attack()。战斗回合调用 Attack() ,角色可以在本回合攻击。意图,当对角色调用 Attack() 时,另一个角色的生命值会改变。目前,角色的健康永远不会改变。有人能给我一个简洁的例子,说明如何以正确的方式更改对象上的值吗?package mainimport (    "fmt"    "math/rand"    "time")//Character health + atk oftype Character struct {    Health, Atk int}//Attack ... Character can Attackfunc (c *Character) Attack(health, atk int) {    health -= atk}//CharacterInterface ... methods for characterstype 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)}
查看完整描述

1 回答

?
MMTTMM

TA贡献1869条经验 获得超4个赞

在 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

Assignment = ExpressionList assign_op ExpressionList .


assign_op = [ add_op | mul_op ] "=" .

每个左侧操作数必须是可寻址的、映射索引表达式或(仅用于 = 赋值)空白标识符。操作数可以用括号括起来。


元组赋值将多值操作的各个元素分配给变量列表。有两种形式。在第一种情况下,右侧操作数是单个多值表达式,例如函数调用、通道或映射操作或类型断言。左侧操作数的数量必须与值的数量相匹配。例如,如果 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函数中,对于 100 次(间隔 [0, 30] of [0, 100)) 的 31 次调用,平均而言,角色被颠倒或交换,enemy(防御者)击退player(攻击者)。交换指向 的指针Characters反映了角色互换。并且玩家的健康状况下降,而不是敌人的。


查看完整回答
反对 回复 2021-12-13
  • 1 回答
  • 0 关注
  • 140 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信