【问题标题】:Have a variable with multiple types in Swift在 Swift 中有一个具有多种类型的变量
【发布时间】:2019-03-30 23:19:45
【问题描述】:

我想要一个变量,它可以有多种类型(我定义的只有一种),比如:

var example: String, Int = 0
example = "hi"

这个变量应该只能保存 Int 和 String 类型的值。

这可能吗?

感谢您的帮助;)

【问题讨论】:

  • 不,不可能

标签: ios swift types


【解决方案1】:

“具有关联值的枚举”可能是您正在寻找的:

enum StringOrInt {
    case string(String)
    case int(Int)
}

您可以分配字符串或整数:

var value: StringOrInt
value = .string("Hello")
// ...
value = .int(123)

检索内容是通过 switch 语句完成的:

switch value {
case .string(let s): print("String:", s)
case .int(let n): print("Int:", n)
}

如果您声明符合Equatable 协议,那么 您还可以检查值是否相等:

enum StringOrInt: Equatable {
    case string(String)
    case int(Int)
}

let v = StringOrInt.string("Hi")
let w = StringOrInt.int(0)
if v == w { ... }

【讨论】:

  • 通用方式:enum Transformer<T: Equatable, U: Equatable> { case first(T); case second(U) }
  • @Carpsen90:在这里(据我了解)OP 要求提供两个 concrete 给定类型(String 或 Int)的值。但是是的,当然,也有通用枚举的用例,例如著名的Result 类型(保存成功值或错误)。
  • 出现错误二元运算符“==”不能应用于两个“StringOrInt”操作数
  • @VishalChaudhari:该代码使用 Swift 4.2 (Xcode 10.1) 和 Swift 5 (Xcode 10.2) 编译,我已经仔细检查过。 – 您使用的是哪个 Xcode 版本?您是否在 enum StringOrInt: Equatable 中添加了“Equatable”一致性?
【解决方案2】:

以下是实现它的方法。完全按照您的预期工作。

protocol StringOrInt { }

extension Int: StringOrInt { }
extension String: StringOrInt { }

var a: StringOrInt = "10"
a = 10 //> 10
a = "q" //> "q"
a = 0.8 //> Error

注意!我不建议您在生产代码中使用它。这可能会让你的队友感到困惑。

UPD: 正如@Martin R 提到的:请注意,这仅“按照惯例”限制了可能的类型。任何模块(或源文件)都可以添加extension MyType: StringOrInt { } 一致性。

【讨论】:

  • 请注意,这仅“按照惯例”限制了可能的类型。任何模块(或源文件)都可以添加extension MyType: StringOrInt { } 一致性。
  • 好话。谢谢!如果您不介意,我会将其添加到答案中。
  • 另外值得注意的是,这仅在 A 或 B 类型是类或结构时才有效。扩展协议时,您不能声明与另一个协议的一致性。具体来说,这意味着你不能创建像 ArrayOrOptional 这样的类型,因为 Optional 是一个协议。
  • 数组或字典有可能吗..我试过了,但不行
  • 我们可以确认 StringOrInt 为 Codable 吗?
【解决方案3】:

不,这对于类、结构等是不可能的。

但是协议是可能的。

你可以这样做:

protocol Walker {
func go()
}
protocol Sleeper {
func sleep()
}

var ab = Walker & Sleeper

甚至

    struct Person {
    var name: String
    }


var ab = Person & Walker & Sleeper

但我不推荐使用这种方式。

这个更有用:

struct Person: Walker, Sleeper {
/// code
}
var ab = Person

【讨论】:

  • “etc”中包含什么?
  • @Carpsen90 类结构,枚举,闭包(函数),元组
  • 这不会达到 OP 的要求 - 协议上的 & 运算符创建一个具有 both 协议要求的新协议,而不是表达结果类型可能只满足一个协议的要求(但总是至少一个)。
【解决方案4】:

您可以使用Tuple。

例子:

let example: (String, Int) = ("hi", 0)

并通过索引访问每个数据:

let stringFromExampleTuple = example.0 // "hi"
let intFromtExampleTuple = example.1 // 0

【讨论】:

    猜你喜欢
    • 2017-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多