尝试创建将保存一组特定值的类型时遇到问题。这是篮球应用程序。
篮球运动员有球衣号码。在某些欧洲国家(例如该应用程序),数字范围为0到99(含)。但是,还有一个可用的附加值00,它与0不同。
我可以为此使用String,但是String可以存储其他值,并且我必须编写其他验证代码。
现在,我正在使用UInt来存储数字。
有没有更好的方法将这些值存储为Swift类型?
这是自定义类型的绝佳用例。绝对不是UInt或任何整数。是#23 +#24 =#47吗?那真是胡言乱语。#99 *#2是什么?再次,胡言乱语。这不是整数。
只是为了更进一步,而“ 00”是合法的球衣号码,而“ 01”则不是。这不仅与“ 1”相同。这不是有效数字。实际上,如果这是NCAA,则大多数数字都是非法的(请参阅第5节第5.b.2条)。
相反,JerseyNumber是它自己的类型。它有自己的法律业务(从技术上讲,它有自己的代数)。
对于JerseyNumber而言,最明智的原始类型是String,因为您希望能够将00与0区分开。我可能会以这种方式实现它,这将为您提供Equatable,Hashable,CustomStringConvertible和更方便的Codable:
struct JerseyNumber: Hashable {
private var string: String
static let legalNumbers = ["0", "1", "2", "3", "4", "5", "00", "10", "11", "12", "13", "14", "15", "20", "21", "22", "23", "24", "25", "30", "31", "32", "33", "34", "35", "40", "41", "42", "43", "44", "45", "50", "51", "52", "53", "54", "55"]
init?(_ string: String) {
guard JerseyNumber.legalNumbers.contains(string) else { return nil }
self.string = string
}
}
extension JerseyNumber: CustomStringConvertible {
var description: String { string }
}
extension JerseyNumber: Codable {
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let value = try container.decode(String.self)
guard let number = JerseyNumber(value) else {
throw DecodingError.dataCorruptedError(in: container,
debugDescription: "Could not decode JerseyNumber: \(value)")
}
self = number
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(string)
}
}
显然,如果这不是NCAA,或者您想要其他数字规则,则可以重新init
执行以强制执行该规则,也可以不以任何对您的问题有意义的方式强制执行。例如,您可以解析字符串,而不是包含大量合法值。这只是一个例子。但基本要点是为此使用自定义类型,而不是UInt。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句