gpt4 book ai didi

ios - 将项目转换到两个选项之一

转载 作者:搜寻专家 更新时间:2023-11-01 07:01:11 25 4
gpt4 key购买 nike

我想知道一种将项目转换为 Type1Type2 的方法。

为了更清楚,让我举个例子

假设我们有两个不同的 struct 继承自 Decodable

struct Decodable1: Decodable { ... }

struct Decodable2: Decodable { ... }

我使用那些 Decodable 来解析从 http 请求中获取的 json。在几个地方,我必须将这些数据用作;

let data1 : [Decodable1] = [...]
let data2 : [Decodable2] = [...]
var data : [Decodable] = []

switch mode {
case .one:
data = data1 as! [Decodable1]
case .two:
data = data2 as! [Decodable2]
}

我知道这种方法非常简单,我认为如果我只在一个地方实现它不会有害。但是,该应用程序实际上依赖于该模式变量(我将其作为 ReSwift State 提供),因此我试图找到一种更简单的方法来实现这一点。喜欢;

let data = (mode == .one) ? data1 : data2

当然这不起作用并抛出类型不匹配错误

有人可以建议一个好的方法吗?

编辑:

此外,除了减少 switch 语句之外,我的意图是轻松到达那些 Decodable 中定义的变量。这意味着无需执行任何 switchif-else 语句。

这可能吗?

EDIT_2:

我正在根据最近的评论修改我的问题。

假设我有一个

class MyClass {
var data1: [Decodable1] = [...]
var data2: [Decodable2] = [...]
var mode: Mode = .One
func myFunc() -> [Decodable] {
//return either data1 or data2 with respect to the mode and already casted to its type.
}
}

这样的函数是否可行?

最佳答案

如果我理解正确,你的问题是重复使用 switch - 为什么不在 enum 中创建一个函数呢? - 例如

// *** OP's code ***
struct Decodable1: Decodable { /*...*/ }
struct Decodable2: Decodable { /*...*/ }
enum Mode { case one, two }

let data1: [Decodable1] = [Decodable1(), Decodable1()]
let data2: [Decodable2] = [Decodable2(), Decodable2()]
var data: [Decodable] = []

var mode: Mode = .one
switch mode {
case .one:
data = data1 //as! [Decodable1] // cast is unnecessary
case .two:
data = data2 //as! [Decodable2] // cast is unnecessary
}
print(data) // [__lldb_expr_18.Decodable1(), __lldb_expr_18.Decodable1()]

// *** Suggestion - extend the mode enum to make the choice... ***
extension Mode {
func which(_ d1: [Decodable1], _ d2: [Decodable2]) -> [Decodable] {
switch self {
case .one:
return data1
case .two:
return data2
}
}
}
// *** Usage ***
print(mode.which(data1, data2)) // [__lldb_expr_18.Decodable1(), __lldb_expr_18.Decodable1()]

根据您的用例(我不清楚),您可能希望考虑 "Either" pattern :

enum Either<L, R> {
case one(L), two(R)
init(_ left: L) { self = .one(left) }
init(_ right: R) { self = .two(right) }
}

extension Either {
internal init?(any: Any) {
if let left = any as? L {
self = .one(left)
} else if let right = any as? R {
self = .two(right)
} else {
return nil
}
}
static func fromAny(_ any: [Any]) -> [Either] {
return any.compactMap({ Either(any: $0) })
}
}

let e = Either<Decodable1, Decodable2>.fromAny(data1)

关于ios - 将项目转换到两个选项之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51176540/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com