当前位置: 首页 > 面试题库 >

在Swift中,如何转换为具有关联类型的协议?

翟单弓
2023-03-14
问题内容

在下面的代码中,我想测试是否xSpecialController。如果是的话,我想currentValue作为SpecialValue。你怎么做到这一点?如果不使用强制转换,则使用其他技术。

那里的最后一行不会编译。错误是: 协议“ SpecialController”仅具有通用要求或关联类型要求,因此只能用作通用约束。

protocol SpecialController {
    associatedtype SpecialValueType : SpecialValue
    var currentValue: SpecialValueType? { get }
}
...
var x: AnyObject = ...
if let sc = x as? SpecialController {  // does not compile

问题答案:

不幸的是,Swift当前不支持将具有关联类型的协议用作实际类型。但是,从技术上讲这对于编译器是可行的。并且很可能在该语言的未来版本中实现。

在您的情况下,一个简单的解决方案是定义一个“影子协议”,该影子协议SpecialController派生自该影子协议,并允许您currentValue通过协议要求进行访问,而协议要求将其擦除:

// This assumes SpecialValue doesn't have associated types – if it does, you can
// repeat the same logic by adding TypeErasedSpecialValue, and then using that.
protocol SpecialValue {
  // ...
}

protocol TypeErasedSpecialController {
  var typeErasedCurrentValue: SpecialValue? { get }
}

protocol SpecialController : TypeErasedSpecialController {
  associatedtype SpecialValueType : SpecialValue
  var currentValue: SpecialValueType? { get }
}

extension SpecialController {
  var typeErasedCurrentValue: SpecialValue? { return currentValue }
}

extension String : SpecialValue {}

struct S : SpecialController {
  var currentValue: String?
}

var x: Any = S(currentValue: "Hello World!")
if let sc = x as? TypeErasedSpecialController {
  print(sc.typeErasedCurrentValue as Any) // Optional("Hello World!")
}


 类似资料:
  • 问题内容: “让f = e为[测试],让g = e为![测试]”总是会出错。我有一个必须发送[Test]到的功能。将A转换为Test易于使用。但是当涉及到数组时,我必须遍历所有数据。有什么好的方法可以将[A]转换为[Test]。 问题答案: 不同代码的答案是正确的,但它也是重要的是要明白,为什么你不能只是重新解释数据,而不 东西 做一个O(n)的转换行走,虽然在一个盒子包装的每个元素。 是一个数组

  • 我为协变返回类型的继承创建了一个小示例。基本上有三种不同的类别: 主应用程序: BaseManager: 鸟经理: 当我重写方法以返回时,为什么我需要将类型转换为? 我使用过的重写方法在返回类型上会有所不同吗?作为参考。 编辑: 我有不同的子模型,它们都继承自。所有模型都允许存在一次。我尝试将这些模型添加到列表中,而不是对每个模型使用单例。使用,我想得到实际的模型。也许我得考虑太多了。

  • 问题内容: 我对一方面用于协议的关联类型的语法和另一方面用于泛型类型的语法之间的区别感到困惑。 例如,在Swift中,可以使用以下方式定义通用类型 而使用诸如 为什么后者不只是: 是否有某种深层的原因(或者也许是显而易见的,对我来说就迷失了),原因是该语言未采用后一种语法? 问题答案: 在开发人员列表中已对此进行了多次讨论。基本答案是关联类型比类型参数更灵活。虽然您在这里有一个类型参数的特定情况,

  • 问题内容: 我想将字符串中包含的字母的索引转换为整数值。尝试读取头文件,但找不到的类型,尽管它似乎符合使用方法的协议(例如)。 任何帮助表示赞赏。 问题答案: 编辑/更新: Xcode 11•Swift 5.1或更高版本 游乐场测试

  • 问题内容: 我有一个协议,该协议继承自另一个协议,并且满足扩展要求。 还有另一种协议,其要求()应该为。 现在,如果我尝试使用as ,那么它将无法编译。它说, 推断的类型“地址”(通过匹配要求“ valueForDetail”)无效:不符合“ Validator”。 这种用法非法吗?我们不能像所有的那样用它代替。 下面是我正在尝试的代码。 更新: 提交了一个错误。 问题答案: David已经提到的

  • 问题内容: 考虑以下代码: 我们感到恐惧,而且显然令人费解: 协议“集合”具有自定义或相关类型要求,因此只能用作通用约束。 但是,这很容易编译: 为什么?! 特别是,编译器 不 知道如何关联的类型(类型)的已经实现; 它只能得到它们已经存在的 承诺 (因为任何类型的对象 都 必须实现它们)。第一个示例中也有同样的保证!那么,为什么编译器抱怨一个而不是另一个呢? 我的问题是:在代码行中,编译器如何知