我的例子太复杂了,所以这里是我想要做的简化版本:
if someVariable {
let thisVariable = 5
} else {
let thisVariable = "This is not a number"
}
print(thisVariable)
我试图在变量上使用相同的代码,无论其类型如何,但我似乎找不到干净利落的方法,因为在if语句中声明的变量不是全局变量。我不能把它变成全局的,因为我不能在if语句之外声明它的类型。有没有一种简单的方法来实现我正在寻找的结果?谢谢!
答案 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
无论您选择哪种方式(协议或子类化),最终目标目标都与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子类上重复属性。