在Swift中你可以将泛型约束为两种类型吗? String和Int

时间:2016-12-09 15:27:21

标签: generics swift3 extension-methods

在Swift3中,你能做到这一点......

 func example<T>()->(T) where T can only be String or Int

或者,你只需要两个扩展名吗?

例如,该函数计算数学函数。

输入在概念上是一个&#34;数字&#34;但它可以是法语字符串,也可以是整数。所以输入可以是String&#34; cent&#34;或者Int 100.结果将是平方根,所以要么字符串&#34; dix&#34;或Int 10。

4 个答案:

答案 0 :(得分:8)

这不是泛型的工作。使用两种类型的静态集合没有任何通用性。

这是使用枚举的完美情况:

enum SomeEnum { //TODO: name me
    case string(String)
    case int(Int)
}

func foo(input: SomeEnum) -> SomeEnum {
    switch input {
        case .string(let s):
            print("This is a String: \(s)")
            return(.string("abc"))
        case .int(let i):
            print("This is an Int: \(i)")
            return(.int(123))
    }
}

print(foo(input: SomeEnum.string("qwerty")))
print(foo(input: SomeEnum.int(5)))

You can try it here

答案 1 :(得分:1)

我在想这样的事情,虽然看起来枚举似乎是一个很好的答案。

protocol HasSquareRootMethod {
    var squareRoot: Int { get }
}
extension Int {
    var squareRoot: Int { return 0 }
}
extension String {
    var squareRoot: Int { return 0 }
}

答案 2 :(得分:0)

其他答案已经演示了如何在一般情况下创建一个约束于两个或更多其他不相关类型的泛型函数。如果这个一般问题是你的问题的真正含义,你就可以去了。

但是,如果您提供的示例用例类似于您实际想要做的事情,那么使用泛型可能并不是您想要的。

  

输入在概念上是一个“数字”,但它可以是法语字符串,也可以是整数。因此输入可以是字符串“cent”或Int 100.结果将是平方根,因此字符串“dix”或Int 10。

这意味着您实际上(至少)有两个问题(and you didn't even use regular expressions!)......

  1. 将用户输入文本转换为数字类型。

    (可能您的最终类型为FloatDouble,因为标准库中的Int未定义平方根等超常函数。另请注意,您必须执行此操作即使用户输入是“数字” - 也就是说,包含数字的字符串 - 因为该字符串可以包含其他字符,这些字符可能会或可能不会影响其作为数字的“含义”。)

  2. 找到数字的平方根。

  3. (可选,可能是也可能不是您完整设计的一部分。)以漂亮的,人类可读的格式呈现答案,可能与用户输入的格式类似。

  4. 步骤2很简单,一旦有了数字。对于步骤1和3,您至少可以开始使用NumberFormatter

    guard let num = formatter.number(from: "one hundred") as? Double
        else { fatalError("better error handling plz") }
    
    let root = sqrt(num)
    
    guard let rootText = formatter.string(from: root as NSNumber)
        else { fatalError("better error handling plz") }
    
    print(rootText) // "ten"
    

    设置formatter.locale = Locale(identifier: "ja_JP"),“十”为“百”,使用fr_FRfr_CA,“分”变为“dix”等。

    但是,解释用户文本总是很乱。如果他们进入“一百二十一”而不是“一百二十一”怎么办?那么“eleventyone”怎么样?如果还有其他无关的字符怎么办? NumbeFormatter无法识别整个可能的自然语言数字表达式。

    您的处理和输出也需要考虑一些逻辑。如果用户输入的数字没有整数平方根,会发生什么?你真的想在你的UI中显示“十点零四九八七五六一二一零九”吗?

    像这样的大问题是将程序中的不同任务分开而不是通过一个通用函数运行所有逻辑的一个很好的理由。 (还有一些简单的原因,比如能够重复使用数字/文本转换代码进行多次数学运算。)

答案 3 :(得分:0)

我们可以像下面这样声明泛型,并提供示例用法,请检查它

 func genericTest<T>(_ a: inout T,  _ b: inout T)
{
 let c = a
  a = b
   b = c
  }
  var a = 10
       var b = 20
       genericTest(&b, &a)
       print("av:\(a)---\(b)")

       var c = "myTest"
       var d = "new Test"
       genericTest(&c, &d)
       print("cv:\(c)---\(d)")