在 Swift 中,您可以将泛型限制为两种类型吗?字符串和整数
In Swift can you constrain a generic to two types? String and Int
在Swift3中,你能做到吗...
func example<T>()->(T) where T can only be String or Int
或者,您是否只需要两个分机?
例如,函数计算一个数学函数。
输入在概念上是 "number",但它可以是法语字符串,也可以是整数。所以输入可以是 String "cent" 或 Int 100。结果将是平方根,因此 String "dix" 或 Int 10.
这不是仿制药的工作。使用两种类型的静态集合没有什么通用之处。
这是使用枚举的完美情况:
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)))
我在想这样的事情,尽管枚举似乎是一个很好的答案。
protocol HasSquareRootMethod {
var squareRoot: Int { get }
}
extension Int {
var squareRoot: Int { return 0 }
}
extension String {
var squareRoot: Int { return 0 }
}
其他答案已经演示了在一般情况下如何创建受限于两个或多个其他不相关类型的泛型函数。如果这个一般性问题是您真正要问的问题,那您就可以开始了。
但是,如果您提供的示例用例与您实际想要做的事情相似,那么使用泛型可能不是您想要的。
The input is conceptually a "number" but it could be either a string in French, or, an integer. So the input could be a String "cent" or an Int 100. the result would be say the square root, so either String "dix" or Int 10.
这意味着您实际上(至少)有两个问题 (and you didn't even use regular expressions!)...
将用户输入的文本转换为数字类型。
(可能您的最终类型是 Float
或 Double
,因为在标准库中的 Int
上未定义像平方根这样的先验函数。另请注意,您有即使用户输入的是“数字”——即包含数字的字符串——也要执行此操作,因为该字符串可以包含其他字符,这些字符可能会或可能不会影响其作为数字的“含义”。)
求数字的平方根。
(可选,可能是也可能不是您的完整设计的一部分。)以漂亮的、人类可读的格式呈现答案,可能类似于用户输入的格式。
第 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_FR
或fr_CA
,“cent”变成“dix”,等等
然而,解释用户文本总是很混乱。如果他们输入“一百二十一”而不是“一百二十一”怎么办? “eleventyone”呢?如果还有其他无关的字符怎么办? NumbeFormatter
无法识别所有可能的自然语言数字表达式。
您在处理和输出中也需要考虑一些逻辑。如果用户输入的数字没有整数平方根会怎样?您真的要在 UI 中显示“十点零四九八七五六二一一二零九”吗?
像这样大而棘手的问题是将程序中的不同任务分开而不是 运行 通过一个通用函数分解所有逻辑的一个很好的理由。 (也有一些简单的原因,例如能够将您的 number/text 转换代码重复用于多个数学运算。)
我们可以像下面这样声明泛型,还提供了示例用法,请查看
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)")
在Swift3中,你能做到吗...
func example<T>()->(T) where T can only be String or Int
或者,您是否只需要两个分机?
例如,函数计算一个数学函数。
输入在概念上是 "number",但它可以是法语字符串,也可以是整数。所以输入可以是 String "cent" 或 Int 100。结果将是平方根,因此 String "dix" 或 Int 10.
这不是仿制药的工作。使用两种类型的静态集合没有什么通用之处。
这是使用枚举的完美情况:
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)))
我在想这样的事情,尽管枚举似乎是一个很好的答案。
protocol HasSquareRootMethod {
var squareRoot: Int { get }
}
extension Int {
var squareRoot: Int { return 0 }
}
extension String {
var squareRoot: Int { return 0 }
}
其他答案已经演示了在一般情况下如何创建受限于两个或多个其他不相关类型的泛型函数。如果这个一般性问题是您真正要问的问题,那您就可以开始了。
但是,如果您提供的示例用例与您实际想要做的事情相似,那么使用泛型可能不是您想要的。
The input is conceptually a "number" but it could be either a string in French, or, an integer. So the input could be a String "cent" or an Int 100. the result would be say the square root, so either String "dix" or Int 10.
这意味着您实际上(至少)有两个问题 (and you didn't even use regular expressions!)...
将用户输入的文本转换为数字类型。
(可能您的最终类型是
Float
或Double
,因为在标准库中的Int
上未定义像平方根这样的先验函数。另请注意,您有即使用户输入的是“数字”——即包含数字的字符串——也要执行此操作,因为该字符串可以包含其他字符,这些字符可能会或可能不会影响其作为数字的“含义”。)求数字的平方根。
(可选,可能是也可能不是您的完整设计的一部分。)以漂亮的、人类可读的格式呈现答案,可能类似于用户输入的格式。
第 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_FR
或fr_CA
,“cent”变成“dix”,等等
然而,解释用户文本总是很混乱。如果他们输入“一百二十一”而不是“一百二十一”怎么办? “eleventyone”呢?如果还有其他无关的字符怎么办? NumbeFormatter
无法识别所有可能的自然语言数字表达式。
您在处理和输出中也需要考虑一些逻辑。如果用户输入的数字没有整数平方根会怎样?您真的要在 UI 中显示“十点零四九八七五六二一一二零九”吗?
像这样大而棘手的问题是将程序中的不同任务分开而不是 运行 通过一个通用函数分解所有逻辑的一个很好的理由。 (也有一些简单的原因,例如能够将您的 number/text 转换代码重复用于多个数学运算。)
我们可以像下面这样声明泛型,还提供了示例用法,请查看
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)")