如何在 Swift 编译时强制使用非可选类型(对于数组元素)?

问题描述 投票:0回答:1
struct MyStruct {
    @ArrayOfNonOptionalElements var arr: [SomeNonOptionalType]
}

其中

@ArrayOfNonOptionalElements
propertyWrapper

那么,如何强制内部类型的非可选性呢?有可能吗? 🙄
我的意思是,如何以这样的方式实现属性包装器,它强制数组元素类型是非可选的。

更新:
好吧,看来没人理解我的问题😣
我希望编译器防止在方括号内添加问号😃

更新2:
将复制/粘贴我在帖子下的评论之一,以便每个人都可以轻松看到它:

我正在编写“@Compact”propertyWrapper 用于安全数组解码。所以 结果将保证不包含任何零。这个性质 包装器可以操作任何数组类型。所以这只是一种 完美主义者的挑战🙂

arrays swift option-type property-wrapper
1个回答
0
投票

你只需要制作

Result
Decodable

extension Result: Decodable where Success: Decodable, Failure == Error {
    public init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        do {
            self = try .success(container.decode(Success.self))
        } catch {
            self = .failure(error)
        }
    }
}

@propertyWrapper
struct Compact<Element>: Decodable where Element: Decodable {
    var wrappedValue: [Element]

    init(
        wrappedValue: [Element]
    ) {
        self.wrappedValue = wrappedValue
    }

    init(from decoder: Decoder) throws {
        let array:[Result<Element, Error>] = try .init(from: decoder)
        self.init(wrappedValue: array.compactMap { result in
            switch result {
            case .success(let success):
                return success
            case .failure:
                return nil
            }
        })
    }
}

struct Ints: Decodable {
    @Compact
    var items: [Int]
}

struct Strings: Decodable {
    @Compact
    var items: [String]
}

struct Floats: Decodable {
    @Compact
    var items: [Float]
}


let data = """
{
    "items" :[1, null, "foo", 2.2, null, "bar", 3]
}
""".data(using:.utf8)!
let ints = try JSONDecoder().decode(Ints.self, from: data)
print(ints.items)

let strings = try JSONDecoder().decode(Strings.self, from: data)
print(strings.items)

let floats = try JSONDecoder().decode(Floats.self, from: data)
print(floats.items)

输出是:

[1, 3] [“富”,“酒吧”] [1.0、2.2、3.0]

如果您需要错误值,您甚至可以使用

Result

struct Ints: Decodable {
    var items: [Result<Int, Error>]
}
© www.soinside.com 2019 - 2024. All rights reserved.