簡體   English   中英

更短的替代三元以生成空字符串如果為零?

[英]Shorter Alternative to ternary to generate empty string if nil?

我有一個類型為Double?的參數Double? . 當此參數為nil ,我想要一個空字符串。

我可以使用if (variable == nil) ? "" : String(variable!) if (variable == nil) ? "" : String(variable!)但有更短的選擇嗎?

使用Optional.map和 nil-coalescing 運算符?? 你可以做

var variable: Double? = 1.0
let string = variable.map { String($0) } ?? ""

如果變量不是nil ,則調用閉包(並返回字符串),否則map返回nil並且表達式計算為空字符串。

我沒有看到簡化代碼的簡單方法。 一個想法是創建一個像這樣的雙擴展:

extension Optional where Wrapped == Double {
    var asString: String {
        self == nil ? "" : String(self!)
    }
}

然后,而不是使用 if 條件:

variable.asString

如果你想在另一個字符串中使用結果字符串,像這樣:

let string = "The value is: \\(variable)"

並可能指定variable nil時要打印的內容:

let string = "The value is: \\(variable, nil: "value is nil")"

你可以為 String.StringInterpolation 編寫一個方便的通用擴展,它接受任何類型的值並打印它,如果它是一個可選的並且也是nil它打印指定的“默認”字符串:

extension String.StringInterpolation {
    mutating func appendInterpolation<T>(_ value: T?, `nil` defaultValue: @autoclosure () -> String) {
        if let value = value {
            appendLiteral("\(value)")
        } else {
            appendLiteral(defaultValue())
        }
    }
}

例子:

var d: Double? = nil
print("Double: \(d, nil: "value is nil")")

d = 1
print("Double: \(d, nil: "value is nil")")

let i = 1
print("Integer: \(i, nil: "value is nil")")

控制台輸出:

Double: value is nil
Double: 1.0
Integer: 1

只是為了好玩,一種涵蓋所有符合 LosslessStringConvertible 類型的通用方法:

extension LosslessStringConvertible {
    var string: String { .init(self) }
}

extension Optional where Wrapped: LosslessStringConvertible {
    var string: String { self?.string ?? "" }
}

var double = Double("2.7")

print(double.string)    // "2.7\n"

屬性包裝器應該可以幫助您提供所需的結果 - 屬性包裝器有一個特殊的變量wrapperValueprojectedValue ,它們可以添加一個分離層並允許您包裝自定義邏輯。

wrappedValue - 使用 getter 和 setter 操作此變量。 在我們的情況下,它的用途很少,因為它是 Double? 類型

投影值- 這將是我們的重點,因為在我們的例子中,我們可以使用這個變量將 Double 投影為字符串。

實現如下

@propertyWrapper
struct DoubleToString {
    private var number: Double = 0.0
    var projectedValue: String = ""
    var wrappedValue: Double?{
        get {
            return number // Not really required
        }
        set {
            if let value = newValue { // Check for nil
                projectedValue = value.description // Convert to string
                number = value
            } 
        }
    }
}

現在我們創建一個使用這個包裝器的結構。

struct NumbersTest {
    @DoubleToString var number1: Double?
    @DoubleToString var number2: Double?
}

在運行下面的代碼時,我們得到了想要的結果。 $number1 為我們提供了projectedValue ,如果我們忽略$ 符號,我們將獲得wrappedvalue

var numbersTest = NumbersTest()
numbersTest.number1 = 25.0
numbersTest.number2 = nil

print(numbersTest.$number1) //"25.0"
print(numbersTest.$number2) //""

通過使用屬性包裝器,您可以保持變量的互操作性,以便輕松獲取 Double 和 String 值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM