可以有多个参数替代方法吗?

时间:2019-08-18 14:15:12

标签: swift xcode parameters

假设我有一个像这样的函数:

func myFunc(myObject: MyObjectA){}

但是,如果我想让myObject成为MyObjectBMyObjectC怎么办?有没有一种方法可以为一个参数和同一个参数提供多个可能的参数替代方法?

注意:我不需要附加参数,我希望同一参数能够采用许多不同的类。像这样:

func myFunc(myObject: MyObjectA || MyObjectB){}

如果您想用我的真实代码提供更详细的方法,请执行以下操作:我有一个战斗function,目前该角色可以攻击敌人。当敌人攻击角色时,我希望能够使用相同的功能。

func combat(character: Character, enemy: Enemy, completion: @escaping() -> Void) {

    let randomNumber = Int(arc4random_uniform(101))
    print(String(character.characterAttack - enemy.enemyDefence), "% chance to hit.")

    if(randomNumber <= (character.characterAttack - enemy.enemyDefence)) {
        enemy.enemyHealth = (enemy.enemyHealth - character.characterDamage)
        print("HIT", randomNumber, "% ", String(enemy.enemyHealth))

    }else{
        print("MISS", randomNumber)
    }
    if(enemy.enemyHealth > 0) {
        print("Enemy has ", String(enemy.enemyHealth), " health left")
    }else{
        print("Enemy Destroyed")
        completion()
    }
}

因此,我希望将其代替character: Character, enemy: Enemy作为attacker: CharacterOrEnemy, defender: EnemyOrCharacter并相应地更改其余函数。

5 个答案:

答案 0 :(得分:3)

使用泛型。您的函数将如下所示:

func myFunc<T>(myObject: T){}

这是仿制药的官方指南

Swift Generics

答案 1 :(得分:3)

不幸的是,您无法以自己想要的方式表现自己的行为。

您可以做的是以下解决方法之一:

  1. 创建具有不同功能签名的多个功能
  2. 使MyObjectAMyObjectB等符合相同的协议或将其归为同一类
  3. 泛型

方法1(多功能)详细信息

func myFunc(myObject: MyObjectA){
}

func myFunc(myObject: MyObjectB){
}

方法2(协议)详细信息:

protocol SomethingProtocol {
}

class MyObjectA: SomethingProtocol {
}

class MyObjectB: SomethingProtocol {
}

func myFunc(myObject: SomethingProtocol){ 
}

方法2(子类别)详细信息:

class SomeClass {
}

class MyObjectA: SomeClass {
}

class MyObjectB: SomeClass {
}

func myFunc(myObject: SomeClass){ 
}

方法3(泛型)详细信息:

func myFunc<T>(myObject: T){
}

正确的解决方案将取决于您的确切用例。

编辑:根据我的个人情况,正确的解决方案应该是创建协议Attackable并使CharacterEnemy符合协议。

答案 2 :(得分:1)

您也可以使用Any

func myFunc(myObject: Any){
   if let objA = myObject as? ObjectA {
       // TODO when myObject is a member of class ObjectA
   }
   // same for objB,C...
}

答案 3 :(得分:1)

您的情况使我想起了我的书中使用通用协议的示例:

protocol Wieldable {
}
struct Sword : Wieldable {
}
struct Bow : Wieldable {
}
protocol Fighter {
    associatedtype Enemy : Fighter
    associatedtype Weapon : Wieldable
    func steal(weapon:Self.Enemy.Weapon, from:Self.Enemy)
}
struct Soldier : Fighter {
    typealias Weapon = Sword
    typealias Enemy = Archer
    func steal(weapon:Bow, from:Archer) {
    }
}
struct Archer : Fighter {
    typealias Weapon = Bow
    typealias Enemy = Soldier
    func steal (weapon:Sword, from:Soldier) {
    }
}

struct Camp<T:Fighter> {
    var spy : T.Enemy?
}

在该示例中,弓箭手和士兵是敌人。弓箭手营中的间谍只能是士兵,反之亦然。士兵只能从弓箭手那里偷弓,反之亦然(也就是说,弓箭手只能从弓箭手那里偷剑)。这似乎与您将角色与敌人配对的想法非常相似。

答案 4 :(得分:0)

您还可以通过Any作为类型并在函数中进行测试。 这是一个玩具示例。

func myFunc(myObject: Any) {
    if let object = myObject as? Int {
        print(object, "This is an Int")
    } else if let object = myObject as? Double {
        print(object, "This is a Double")
    } else {
        print(myObject, "This is not an Int nor Double")
    }
}

let x = myFunc(myObject: 5)
let y = myFunc(myObject: 5.0)
let z = myFunc(myObject: "Hello")

收益

5 This is an Int
5.0 This is a Double
Hello This is not an Int nor Double