【问题标题】:How can I make Swift's String type conform to the CVarArgType protocol?如何使 Swift 的 String 类型符合 CVarArgType 协议?
【发布时间】:2016-03-16 20:08:43
【问题描述】:

Swift 协议定义为空:

public protocol CVarArgType {
}

Apple 文档页面没有列出任何必需的方法: https://developer.apple.com/library/ios/documentation/Swift/Reference/Swift_CVarArgType_Protocol/index.html

所以我希望这会起作用:

extension String : CVarArgType {

}

但我得到一个构建错误:Protocol requires property '_cVarArgEncoding' with type '[Int]' (Swift.CVarArgType)

鉴于协议定义为空,此要求从何而来?

如果我实现计算属性,则继续前进:

extension String : CVarArgType {
    public var _cVarArgEncoding: [Int] {
        get {
            //What is expected to be returned here?
        }
    }
}

预计会以Int 的数组形式返回什么?

更新:我为什么需要这个?

我有一个名为 Identifiable 的协议,我的核心数据实体模型类符合该协议,我对该协议进行了扩展,并带有几个约束,以提供一个函数,该函数使用 NSPredicate 中的 id 值和格式构造函数,该构造函数需要 CVarArgType .

public protocol Identifiable {
    typealias IdentityType: CVarArgType, Hashable
    var id: IdentityType { get }
}

extension Identifiable where Self: Findable, Self: NSManagedObject {

    static public func find(id: IdentityType, context: NSManagedObjectContext) -> Self? {
        return find(NSPredicate(format: "id = %@", id), context: context)
    }

}

public extension Findable where Self: NSManagedObject {

    static public func find(predicate: NSPredicate?, context: NSManagedObjectContext) throws -> Self? {
        let fetchRequest = fetchRequestForEntity(inContext: context)
        fetchRequest.predicate = predicate
        fetchRequest.fetchLimit = 1
        return try context.executeFetchRequest(fetchRequest).first as? Self
    }

}

【问题讨论】:

  • 我认为这没什么实用价值,有更好的方法来处理va_list 参数。但是,我认为这个问题仍然有一些优点,因为它探索了 ObjectiveC-Swift 集成的边缘。编码可以参考ObjectiveC type encoding。如果你能解释你想做什么,我们可以提供更多帮助
  • @CodeDifferent 我已更新问题以提供更多上下文
  • 能不能不用NSPredicate的arrayArgument init? - init(format predicateFormat: String, argumentArray arguments: [AnyObject]?)
  • 不,我收到构建错误Value of type 'Self.IdentityType' does not conform to expected element type 'AnyObject'
  • 您的协议没有从 NSObjectProtocol 继承,应该可以解决这个问题。无论如何,结构和枚举可能无法与 NSPredicate 很好地混合。实际上,您可以将其转换为 AnyObject,因为它是此扩展中的 NSManagedObject。

标签: swift


【解决方案1】:

我认为您不应该尝试使其他类型符合它们。 Swift source code 说:

注意:协议是公共的,但它的要求是 stdlib-private。 这是因为有 API 在 CVarArg 实例上运行,但不支持在标准库之外定义与 CVarArg 的一致性。

stdlib 在很多方面都很特别,并且比用户代码更能深入构建系统。一个例子是许多 stdlib 函数可以内联到您自己的代码中,这在其他情况下目前无法跨模块边界。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多