douxi4114 2016-02-13 22:34 采纳率: 100%
浏览 25
已采纳

更改结构属性值

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

Trying to get my head around Go, still pretty new. I know refs and pointers in C and I can't seem to get it working in 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().

Combat round calls Attack() on which Character can attack this round.

Intent, when Attack() is called on Character, health is changed on another 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 
 Enemy Health: %d", p.Health, e.Health)

}
  • 写回答

1条回答 默认 最新

  • dongpigui8898 2016-02-13 23:54
    关注

    In Go, the parameters and receivers of a call to a function or method are always passed by value (by assignment).

    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
    Enemy Health: %d
    ", 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

    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,

    x, y = f()
    

    assigns the first value to x and the second to 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:

    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

    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). Swapping the pointers to the Characters reflects the role reversal. and the player's health declines, not the enemy's.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题