2013-09-21 38 views
1

上下文:我们来创建一个百分比编码器。所以,字符将被编码为他们的%表示。另外,我想将字符串向量编码如下:[a b] -> (str (encode a) "+" (encode b))。背后的原因是我想要空间被编码为%20的字符串和+猫编辑的字符串列表。我使用协议做到这一点:Clojure:为列表和字符串做些什么

(defprotocol IUrlEncodable 
    (^String url-encode [v])) 

(extend-protocol IUrlEncodable 
    String 
    ;; Do I need type here? I have it in the protocol. 
    (^String url-encode [v] 
    (-> v URLEncoder/encode (.replace "+" "%20"))) 
    IPersistentVector 
    ;; Same question here. 
    (^String url-encode [v] 
    (->> v (map url-encode) (join "+")))) 

它是一个规范的方式来做到这一点?我做了正确的事情吗?什么是替代品?我是否需要在协议扩展中重新声明类型提示,如果我已经在协议中声明了它?

回答

3

只有协议功能上的类型提示很重要;方法实现中的类型提示没有任何用处。严格来说,编译器将使用附加到Vars函数的类型提示。这里讨论的变种 - #'url-encode - 由defprotocol表单(以及#'IUrlEncodable,其中包含一些协议管理机构和相关的JVM接口)创建。附加到url-encode方法名称的元数据将被传输到此Var。在调用extend & Co.时命名此方法的符号中附加的元数据没有相关性。

请注意,从技术上讲,根本不需要任何类型提示,但如果确实将它们放入,它们可以帮助编译器避免在某些情况下进行反射。

+0

不,在函数文本中附加到'url-encode'的类型提示被附加到'#'url-encode' Var,并被解释为与返回值有关。附加到参数上的类型提示是一个不同的问题 - 实际上需要在实现中指定这些提示。 (注意,不应该在前导“this”参数中指定类型提示,因为它的类型是已知的。) –

+0

(以上是针对明显被删除的评论的回答,问题是类型提示是否适用于参数'v'而不是函数'url-encode'。) –

+0

总的来说,我的代码是否习惯?我的意思是协议适合在这里? – demi

相关问题