草庐IT

ios - 将泛型 AnyObject 向下转换为协议(protocol)关联类型 Self.Model

coder 2023-07-16 原文

我正在开发一个库 Restofire我想在其中保留一个配置对象。我想在配置对象中有一个 ResponseSerializer,但问题是 ResponseSerializer 是一个通用的。

public struct Configuration<M> {

    /// The Default `Configuration`. 
    static let defaultConfiguration = Configuration<AnyObject>()

    /// The base URL. `nil` by default.
    public var baseURL: String!

    /// The `ResponseSerializer`
    public var responseSerializer: ResponseSerializer<M, NSError> = AlamofireUtils.JSONResponseSerializer()

    /// The logging, if enabled prints the debug textual representation of the 
    /// request when the response is recieved. `false` by default.
    public var logging: Bool = false

}

我使用 baseUrl Configuration.defaultConfiguration.baseUrl = "http://httpbin.org/" 设置默认配置

我有一个带有 associatedType 要求的协议(protocol),它使用 defaultConfiguration 作为默认实现。但是我需要将通用 AnyObject 更改为关联类型模型,以便配置对象的 responseSerializer 返回类型模型。

public protocol Configurable {

    associatedtype Model

    /// The Restofire configuration.
    var configuration: Configuration<Model> { get }

}

public extension Configurable {

    /// `Restofire.defaultConfiguration`
    // Cannot convert return expression of Configuration<AnyObject> to return type Configuration <Self.Model>
    public var configuration: Configuration<Model> {
        return Restofire.defaultConfiguration
    }

}

我收到错误 Cannot convert return expression of Configuration<AnyObject> to return type Configuration <Self.Model>

我如何向下转型以使用 Model 而不是 AnyObject ?

我还有一个继承自 Configurable 的 Requestable 协议(protocol)

public protocol Requestable: Configurable {

    /// The type of object returned in response.
    associatedtype Model

    /// The base URL.
    var baseURL: String { get }

    /// The path relative to base URL.
    var path: String { get }

    /// The request parameters.
    var parameters: AnyObject? { get }

    /// The logging.
    var logging: Bool { get }

    /// The Response Serializer
    var responseSerializer: ResponseSerializer<Model, NSError> { get  }
}

// MARK: - Default Implementation
public extension Requestable {

    /// `configuration.BaseURL`
    public var baseURL: String {
        return configuration.baseURL
    }

    /// `nil`
    public var parameters: AnyObject? {
        return nil
    }

    /// `configuration.logging`
    public var logging: Bool {
        return configuration.logging
    }

    /// `configuration.responseSerializer`
    var responseSerializer: ResponseSerializer<Model, NSError> {
         return configuration.responseSerializer
    } 

}

RealCode 位于 https://github.com/Restofire/Restofire/compare/Add/DefaultResponseSerializer

我可以直接在下面做,但是用户将无法使用配置对象来设置它。

// MARK: - Default Implementation
public extension Requestable {

    /// `configuration.responseSerializer`
    var responseSerializer: ResponseSerializer<Model, NSError> {
         return AlamofireUtils.JSONResponseSerializer()
    } 

}

还有其他办法吗?

最佳答案

你想做的事是不可能的。这是因为 Swift 中强大的类型安全系统。

您似乎想限制 configuration关联类型 Model ,但您还想提供默认配置。这里的问题是您的默认配置无法保证其泛型类型与 Model 的类型相同。 .

Swift 类型系统不会让你通过 <AnyObject>作为类型 <Model> ,因为它无法确保对象实际上是 Model 的类型。

当你使某物符合 Configurable 时并声明 Model 的类型,你说的是,“我的配置必须使用我给定的类型。” defaultConfiguration不能保证,所以不能这样使用。

通过查看您的代码,您正在使用它来确定 responseSerializer 的类型使用。但是,如果您使用不同的 Configurable对象,它们都需要不同的 responseSerializer s,所以他们不能都使用默认配置。

我花了很多时间思考这个问题,但我没有找到任何解决办法。您将不得不以某种方式更改您的设计。

如果你移动 responseSerializerConfigurable 上协议(protocol),那么你可以制作 Configuration非通用的。在这种情况下,您将能够创建 responseSerializerConfigurable 上的协议(protocol)扩展中.如果您需要使用 responseSerializer具有独立于 Configurable 的配置对象,那么你必须创建一个 responseSerializer<AnyObject, NSError>无论您在哪里使用它。我不熟悉你们图书馆的整个设计和意图,所以我不确定这是否适用于你们想要实现的目标。

我可以肯定地告诉您的一件事是,您的设计必须更改才能使用 defaultConfiguration .

关于ios - 将泛型 AnyObject 向下转换为协议(protocol)关联类型 Self.Model,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36835552/

有关ios - 将泛型 AnyObject 向下转换为协议(protocol)关联类型 Self.Model的更多相关文章

  1. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  2. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  3. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  4. ruby - 将散列转换为嵌套散列 - 2

    这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[

  5. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  6. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  7. ruby-on-rails - Ruby url 到 html 链接转换 - 2

    我正在使用Rails构建一个简单的聊天应用程序。当用户输入url时,我希望将其输出为html链接(即“url”)。我想知道在Ruby中是否有任何库或众所周知的方法可以做到这一点。如果没有,我有一些不错的正则表达式示例代码可以使用... 最佳答案 查看auto_linkRails提供的辅助方法。这会将所有URL和电子邮件地址变成可点击的链接(htmlanchor标记)。这是文档中的代码示例。auto_link("Gotohttp://www.rubyonrails.organdsayhellotodavid@loudthinking.

  8. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  9. ruby-on-rails - 使用 ruby​​ 将多个实例变量转换为散列的更好方法? - 2

    我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。

  10. ruby - Rails 关联 - 同一个类的多个 has_one 关系 - 2

    我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下

随机推荐