[英]Is it possible to change Swift String Interpolation for the String typealias?
我的應用程序中有很多 DTO,它們記錄了一些字段。 不應記錄該字段,因為數據有點敏感。 model 看起來像這樣:
typealias HiddenFieldType = String
struct DTO1 {
var field1_1: String
var fieldToHide: HiddenFieldType
var field1_2: String
var field1_3: String
}
struct DTO2 {
var field2_1: String
var field2_2: String
var fieldToHide: HiddenFieldType
var field2_3: String
}
輸出數據的代碼是這樣的(實際上它是真實應用程序中的os_log
):
func test() {
let dto1 = DTO1(field1_1: "1_1", fieldToHide: "super-secret-1", field1_2: "1_2", field1_3: "1_3")
let dto2 = DTO2(field2_1: "2_1", field2_2: "2_2", fieldToHide: "super-secret-2", field2_3: "2_3")
print("Test1: dto1=\(dto1) dto2=\(dto2)")
}
似乎可以使用以下代碼將該字段隱藏在 DTO1 中:
extension String.StringInterpolation {
mutating func appendInterpolation(_ value: DTO1) {
appendInterpolation("field1_1: \(value.field1_1), fieldToHide: 🤷♀️, field1_2: \(value.field1_2), field1_3: \(value.field1_3)")
}
}
但是,該解決方案既不可擴展也不可維護:
appendInterpolation
——很多樣板文件appendInterpolation
等 我試圖為HiddenFieldType
添加插值(假設它是一種類型,就像DTO1
...):
extension String.StringInterpolation {
mutating func appendInterpolation(_ value: HiddenFieldType) {
appendInterpolation("🤷♀️")
}
}
但是這個解決方案根本不起作用:
appendInterpolation
更改為appendLiteral
時,沒有遞歸,但未隱藏“super-secret-1” 我嘗試覆蓋DefaultStringInterpolation
,符合ExpressibleByStringLiteral
/ ExpressibleByStringInterpolation
,但它不起作用:編譯器說HiddenFieldType
是String
,並且Conformance of 'String' to protocol 'ExpressibleByStringLiteral' was already stated in the type's module 'Swift'
我能想到的唯一方法是將typealias HiddenFieldType = String
更改為struct HiddenFieldType { let value: String }
,因此HiddenFieldType
成為“真實”類型。
然后這樣的代碼不再導致無限遞歸,但也不起作用(值未隱藏)
struct HiddenFieldType {
let value: String
}
extension String.StringInterpolation {
mutating func appendInterpolation(_ value: HiddenFieldType) {
appendInterpolation("🤷♀️")
}
}
這段代碼終於起作用了:
struct HiddenFieldType {
let value: String
}
extension HiddenFieldType: CustomStringConvertible {
var description: String {
"🤷♀️"
}
}
我無法想象更好,現在我會使用這種方法,但它也有一些輕微的可擴展性問題,因為我必須更新每個DTO
的初始化點:從
let dto1 = DTO1(field1_1: "1_1", fieldToHide: "super-secret-1", field1_2: "1_2", field1_3: "1_3")
到
let dto1 = DTO1(field1_1: "1_1", fieldToHide: .init(value: "super-secret-1"), field1_2: "1_2", field1_3: "1_3")
我希望只在包含typealias HiddenFieldType = String
的文件中添加一些擴展名,而不是更新整個代碼。
HiddenFieldType
的值而不將其從typealias
更改為struct
並且不更新每個DTO
?提前致謝
是否可以隱藏 HiddenFieldType 的值而不將其從 typealias 更改為 struct
我認為您正在嘗試使用錯誤的工具來完成這里的工作。 typealias
只是一個名稱更改,聽起來您想要的東西與String
的行為根本不同(即,一個在傳遞到os_log
調用時被打印出來,而另一個則沒有)。 您將無法編寫處理String
與其類型別名不同的typealias
; 編譯器不區分它們。
是否可以制作DTO
的類而不是結構? (編輯:見下文,您可以將它們保留為結構並僅使用協議擴展)如果是這樣,您可以在超類上使用反射來完成此操作,而無需手動為每個不同的 DTO 指定description
。
struct HiddenFieldType {
let value: String
}
open class DTO: CustomStringConvertible {
public var description: String {
Mirror(reflecting: self).children.compactMap { $0.value as? String }.joined(separator: "\n")
}
}
final class DTO1: DTO {
let field1_1: String
let field1_2: String
let fieldToHide: HiddenFieldType
init(field1_1: String, field1_2: String, fieldToHide: HiddenFieldType) {
self. field1_1 = field1_1
self. field1_2 = field1_2
self. fieldToHide = fieldToHide
}
}
請注意,我在description
中包括了所有字符串,但是,如果您想要記錄除String
和HiddenFieldType
以外的類型,您總是可以專門filter
掉HiddenFieldType
。
就個人而言,我會猶豫是否要對任何關鍵代碼依賴反射,但其他人對此有更多的容忍度,因此這是一個判斷電話。
編輯:您不需要使用 inheritance 來完成此操作。 DTO
應該是符合CustomStringConvertible
的協議,而不是超類:
protocol DTO: CustomStringConvertible {}
extension DTO {
public var description: String {
Mirror(reflecting: self).children.compactMap { $0.value as? String }.joined(separator: "\n")
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.