简体   繁体   English

更改结构属性值

[英]Go change struct property values

http://openmymind.net/Things-I-Wish-Someone-Had-Told-Me-About-Go/ http://openmymind.net/Things-I-Wish-Someone-Had-Told-Me-About-Go/

Trying to get my head around Go, still pretty new. 试图绕过Go前进,这还是很新的。 I know refs and pointers in C and I can't seem to get it working in Go. 我知道C中的引用和指针,但似乎无法在Go中使用它。 I've read a number of articles on the issue, and still not really managing to understand and implement a solution. 我已经阅读了许多有关此问题的文章,但仍然无法真正理解和实施解决方案。

Characters have health and atk points. 角色具有生命值和攻击点。

Chars can Attack(). 字符可以Attack()。

Combat round calls Attack() on which Character can attack this round. 战斗回合调用Attack(),角色可以在该回合上攻击。

Intent, when Attack() is called on Character, health is changed on another Character. 意图是,当在Character上调用Attack()时,将在另一个Character上更改运行状况。

Currently Health never changes on Characters. 当前,健康永远不会改变角色。

Can someone give me a concise example of how to change the values on objects around the RIGHT way? 有人可以给我一个简单的示例,说明如何以正确的方式更改对象的值吗?

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)

}

In Go, the parameters and receivers of a call to a function or method are always passed by value (by assignment). 在Go中,对函数或方法的调用的参数和接收者始终按值(按赋值)传递。

For example, 例如,

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)
}

Output: 输出:

$ 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 Go编程语言规范

Assignments 分配

 Assignment = ExpressionList assign_op ExpressionList . assign_op = [ add_op | mul_op ] "=" . 

Each left-hand side operand must be addressable, a map index expression, or (for = assignments only) the blank identifier. 每个左侧操作数都必须是可寻址的,映射索引表达式或(仅用于=赋值)空白标识符。 Operands may be parenthesized. 操作数可以加括号。

A tuple assignment assigns the individual elements of a multi-valued operation to a list of variables. 元组分配将多值操作的各个元素分配给变量列表。 There are two forms. 有两种形式。 In the first, the right hand operand is a single multi-valued expression such as a function call, a channel or map operation, or a type assertion. 首先,右侧操作数是单个多值表达式,例如函数调用,通道或映射操作或类型断言。 The number of operands on the left hand side must match the number of values. 左侧的操作数数量必须与值的数量匹配。 For instance, if f is a function returning two values, 例如,如果f是一个返回两个值的函数,

 x, y = f() 

assigns the first value to x and the second to y. 将第一个值分配给x,第二个值分配给y。 In the second form, the number of operands on the left must equal the number of expressions on the right, each of which must be single-valued, and the nth expression on the right is assigned to the nth operand on the left: 在第二种形式中,左边的操作数的数量必须等于右边的表达式的数量,每个表达式都必须是单值,并且右边的第n个表达式被分配给左边的第n个操作数:

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

The assignment proceeds in two phases. 作业分两个阶段进行。 First, the operands of index expressions and pointer indirections (including implicit pointer indirections in selectors) on the left and the expressions on the right are all evaluated in the usual order. 首先,左侧的索引表达式和指针间接操作(包括选择器中的隐式指针间接操作)和右侧的表达式的操作数均按通常的顺序求值。 Second, the assignments are carried out in left-to-right order. 其次,分配是从左到右执行的。

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

The Go statement Go语句

player, enemy = enemy, player

is the second form of a tuple assignment. 是元组分配的第二种形式。 It's the idiomatic way to swap or exchange two values. 这是交换或交换两个值的惯用方式。 The operands on the left and the expressions on the right are evaluated before the assignments take place. 在进行赋值之前,先评估左侧的操作数和右侧的表达式。 The compiler takes care of any temporary variables for you. 编译器会为您处理所有临时变量。

In the combatRound function, for 31 out ot 100 (interval [0, 30] of [0, 100)) calls, on average, roles are reversed or swapped, the enemy (defender) repulses the player (attacker). combatRound功能中,对于ot 100中的31个([ combatRound间隔[ combatRound ]),平均而言,角色被颠倒或交换, enemy (防御者)击退player (攻击者)。 Swapping the pointers to the Characters reflects the role reversal. 交换指针到Characters反映了角色转换。 and the player's health declines, not the enemy's. 而且玩家的生命值下降,而不是敌人的生命值下降。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM