如何根据swift中if语句的结果创建不同类型的变量?

时间:2017-01-13 17:40:50

标签: swift

我的例子太复杂了,所以这里是我想要做的简化版本:

    if someVariable {
        let thisVariable = 5
    } else {
        let thisVariable = "This is not a number"
    }

    print(thisVariable)

我试图在变量上使用相同的代码,无论其类型如何,但我似乎找不到干净利落的方法,因为在if语句中声明的变量不是全局变量。我不能把它变成全局的,因为我不能在if语句之外声明它的类型。有没有一种简单的方法来实现我正在寻找的结果?谢谢!

3 个答案:

答案 0 :(得分:5)

对于您的简单示例,您可以使用Any类型的变量:

let thisVariable: Any
if someVariable {
    thisVariable = 5
} else {
    thisVariable = "This is not a number"
}

甚至:

let thisVariable: Any = someVariable ? 5 : "This is not a number"

但这可能不是您真实,更复杂的案例的最佳解决方案。

答案 1 :(得分:1)

Swift是强类型的,因此thisVariable类型必须在编译时知道。你可以在其中包装其他类型的实例Any,或使用具有关联值的案例构建您自己的enum不同类型实例包装器。

enum TypeWrapper {
    case `string`(String)
    case `int`(Int)
}

func foo(_ someVariable: Bool) -> TypeWrapper {
    return someVariable ? .int(5) : .string("This is not a number")
}

let thisVariable = foo(true)  // .int(5)
let thatVariable = foo(false) // .string("This is not a number")

但最后,thisVariable被强类型为TypeWrapper

答案 2 :(得分:0)

  嗯,完全回答我的问题,但我意识到它并没有   像你说的解决我的问题。在我的原始代码中,我正在创建   tableView中的自定义单元格,我希望它们选择哪个自定义单元格   基于一些标准。我希望能够写一个if语句   测试标准,然后让cell =自定义单元格I的类型   想。问题是,我未来的代码会更改单元格中的标签   每个自定义单元格的名称相同。当我使用type" Any,"它只是   后来说," Any类型的值没有成员" labelName。"

对于您的具体问题,您可以通过三种不同的方式逃脱:

创建一个协议,您的单元格将全部采用,如下所示:

protocol UserDataPresentable {
    var nameLabel: UILabel? { get set }
    var surnameLabel: UILabel? { get set }
}

class CustomTableViewCell: UITableViewCell, UserDataPresentable {
    var nameLabel: UILabel?
    var surnameLabel: UILabel?
}

extension ViewController: UITableViewDataSource {
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

        if let cell = cell as? UserDataPresentable {
            cell.nameLabel?.text = "John"
            cell.surnameLabel?.text = "Doe"
        }

        return cell
    }
}

创建自定义父级并将其子类化:

class UserPresentableCell: UITableViewCell {
    var nameLabel: UILabel?
    var surnameLabel: UILabel?
}

class FriendCell: UserPresentableCell {
//    ...
}

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "friendCell", for: indexPath)

        if let cell = cell as? UserPresentableCell {
            cell.nameLabel?.text = "John"
            cell.surnameLabel?.text = "Doe"
        }

        return cell
    }
}

BTW,请查看该文章到avoid strings as identifiers

并使用cocoapod IDPCastable

无论您选择哪种方式(协议或子类化),最终目标目标都与IDPCastable相似:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cellType = (indexPath.row % 2) == 0 ? FriendCell.self : UserCell.self
        let cell = tableView.dequeueReusableCell(withType: cellType, for: indexPath)

    return match(cell) { (c: UserPresentableCell) in
        c.nameLabel?.text = "John"
        c.surnameLabel?.text = "Doe"
    }
}

我在你的情况下选择子类化,顺便说一句,以避免在不同的UITableViewCell子类上重复属性。