是否可以在Swift元组中使用nil值?

时间:2015-04-07 10:44:13

标签: swift tuples null

我正在尝试编写一些代码,用于将一些测试数据播种到我正在开发的关于神奇宝贝的应用程序的Core Data数据库中。我的播种代码基于:http://www.andrewcbancroft.com/2015/02/25/using-swift-to-seed-a-core-data-database/

虽然我有一点问题。我似乎无法在元组中添加零值。

我正在尝试将一些神奇宝贝动作播种到数据库中。移动可以有许多不同的属性,但它具有哪种组合完全取决于移动本身。所有种子移动数据都在一个元组数组中。

示范......

let moves = [
    (name: "Absorb", moveType: grass!, category: "Special", power: 20, accuracy: 100, powerpoints: 25, effect: "User recovers half the HP inflicted on opponent", speedPriority: 0),
    // Snip
]

......很好。这是一个包含所有上述属性的举动,其中speedPriority为零意味着什么。但是,某些动作没有强大准确性属性,因为它们与该特定动作无关。但是,在数组中创建第二个元组而没有准确性命名元素,例如......

(name: "Acupressure", moveType: normal!, category: "Status", powerpoints: 30, effect: "Sharply raises a random stat", speedPriority: 0)

......可以理解地抛出错误

  

元组类型{firstTuple}和{secondTuple}具有不同数量的元素(8对6)

因为,元组具有不同数量的元素。所以相反,我试过......

(name: "Acupressure", moveType: normal!, category: "Status", power: nil, accuracy: nil, powerpoints: 30, effect: "Sharply raises a random stat", speedPriority: 0)

但这也没有用,因为它给出了错误:

  

类型'Int'不符合协议'NilLiteralConvertible'

那么,有什么方法可以做我想做的事情吗?有没有办法在元组中放置一个nil值,或以某种方式使它成为一个可选元素?谢谢!

3 个答案:

答案 0 :(得分:6)

您可以执行以下操作:

typealias PokemonMove = (name: String?, category: String?)

var move1 : PokemonMove = (name: nil, category: "Special")

let moves: [PokemonMove] = [
    (name: nil, category: "Special"),
    (name: "Absorb", category: "Special")
]

根据需要添加更多参数,我只使用了两个参数来解释概念。

答案 1 :(得分:2)

在教程中,元组只包含两个值 - namelocation。 由于你在一个元组中有这么多变量,你应该把它们放在一个类或结构中。

使用Structs或Classes也可以使变量很容易为零。并且,由于可选类型在设置每次移动时都具有默认值nil,因此您只需设置非零值 - 如第二个示例所示。

示例Struct是:

struct Move {
    var name: String?
    var moveType: String?
    var category: String?
    var power: Int?

    // etc etc...
}

然后你可以创建一个移动:

var move = Move()
move.name = "Acupressure"
move.category = "Status"
// Don't need to set move.power to nil - it is already!

在教程中,你需要枚举你的元组数组,为了使它与Structs一起工作它基本上看起来是一样的:

let moves: [Move] = // My array of moves
for move in moves {
    let newMove = NSEntityDescription.insertNewObjectForEntityForName("Move", inManagedObjectContext: context) as CoreDataMove
    newMove.name = move.name
    newMove.moveType = move.moveType
    newMove.category = move.category

    // etc etc
}

答案 2 :(得分:1)

您可以使用以下方式实现:

import Foundation

let myNil : Any? = nil

let moves = [
    (name: 1 as NSNumber, other: ""),
    (name: myNil, other: "" )
]

moves[0].name // 1
moves[1].name // nil