关于在 Swift 中使用通用类型扩展 Optional 的问题
Issue about extending Optional with Generic Type in Swift
我试图为安全解包做一个扩展,我正在使用它的两个版本,一个长代码形式,第二个短代码!但没想到它们不起作用!就我所看到的代码而言,我只是把所有事情都弄对了!我缺少什么来修复这两个版本?
struct ContentView: View {
let test: String? = "Hello, World!"
var body: some View {
Text(test.safeUnwrapV1(defaultValue: "Empty!"))
Text(test.safeUnwrapV2(defaultValue: "Empty!"))
}
}
extension Optional {
func safeUnwrapV1<T>(defaultValue: T) -> T {
let wrappedValue: T? = (self as? T?) ?? nil
if let unwrappedValue: T = wrappedValue { return unwrappedValue }
else { return defaultValue }
}
func safeUnwrapV2<T>(defaultValue: T) -> T {
return (self as? T) ?? defaultValue
}
}
像这样制作你的扩展程序。
extension Optional {
func safeUnwrapV1<T>(defaultValue: T) -> Wrapped {
guard let value = self else {
return defaultValue as! Wrapped
}
return value
}
}
编辑: 正如@Rudedog 建议无需在此处定义泛型
extension Optional {
func safeUnwrapV1(defaultValue: Wrapped) -> Wrapped {
guard let value = self else {
return defaultValue
}
return value
}
}
无需定义您自己的泛型类型参数。 Optional
已经是泛型,其泛型类型参数称为 Wrapped
。所以你只需要将默认值的类型声明为 Wrapped
.
extension Optional {
func defaultValue(_ value: Wrapped) -> Wrapped {
self ?? value
}
}
struct ContentView: View {
let test: String? = "Hello, World!"
var body: some View {
Text(test.defaultValue("Empty!"))
}
}
extension Optional {
func safeUnwrap(_ defaultValue: Wrapped) -> Wrapped {
switch self {
case let value?: return value
case nil: return defaultValue
}
}
}
甚至
extension Optional {
func safeUnwrap(_ defaultValue: Wrapped) -> Wrapped {
self ?? defaultValue
}
}
但正如所指出的,这比仅使用 ??
运算符更冗长且不那么惯用。
我会将 Optional
通用 Wrapped
类型限制为 LosslessStringConvertible
:
extension LosslessStringConvertible {
var string: String { .init(self) }
}
extension Optional where Wrapped: LosslessStringConvertible {
var string: String { self?.string ?? "" }
func string(default value: Wrapped) -> String {
self?.string ?? value.string
}
}
用法:
var double1 = Double("2.7")
var double2 = Double("a")
print(double1.string(default: 0))
print(double2.string(default: 0))
这将打印:
2.7
0
我试图为安全解包做一个扩展,我正在使用它的两个版本,一个长代码形式,第二个短代码!但没想到它们不起作用!就我所看到的代码而言,我只是把所有事情都弄对了!我缺少什么来修复这两个版本?
struct ContentView: View {
let test: String? = "Hello, World!"
var body: some View {
Text(test.safeUnwrapV1(defaultValue: "Empty!"))
Text(test.safeUnwrapV2(defaultValue: "Empty!"))
}
}
extension Optional {
func safeUnwrapV1<T>(defaultValue: T) -> T {
let wrappedValue: T? = (self as? T?) ?? nil
if let unwrappedValue: T = wrappedValue { return unwrappedValue }
else { return defaultValue }
}
func safeUnwrapV2<T>(defaultValue: T) -> T {
return (self as? T) ?? defaultValue
}
}
像这样制作你的扩展程序。
extension Optional {
func safeUnwrapV1<T>(defaultValue: T) -> Wrapped {
guard let value = self else {
return defaultValue as! Wrapped
}
return value
}
}
编辑: 正如@Rudedog 建议无需在此处定义泛型
extension Optional {
func safeUnwrapV1(defaultValue: Wrapped) -> Wrapped {
guard let value = self else {
return defaultValue
}
return value
}
}
无需定义您自己的泛型类型参数。 Optional
已经是泛型,其泛型类型参数称为 Wrapped
。所以你只需要将默认值的类型声明为 Wrapped
.
extension Optional {
func defaultValue(_ value: Wrapped) -> Wrapped {
self ?? value
}
}
struct ContentView: View {
let test: String? = "Hello, World!"
var body: some View {
Text(test.defaultValue("Empty!"))
}
}
extension Optional {
func safeUnwrap(_ defaultValue: Wrapped) -> Wrapped {
switch self {
case let value?: return value
case nil: return defaultValue
}
}
}
甚至
extension Optional {
func safeUnwrap(_ defaultValue: Wrapped) -> Wrapped {
self ?? defaultValue
}
}
但正如所指出的,这比仅使用 ??
运算符更冗长且不那么惯用。
我会将 Optional
通用 Wrapped
类型限制为 LosslessStringConvertible
:
extension LosslessStringConvertible {
var string: String { .init(self) }
}
extension Optional where Wrapped: LosslessStringConvertible {
var string: String { self?.string ?? "" }
func string(default value: Wrapped) -> String {
self?.string ?? value.string
}
}
用法:
var double1 = Double("2.7")
var double2 = Double("a")
print(double1.string(default: 0))
print(double2.string(default: 0))
这将打印:
2.7
0