请在2024年Clojure调查报告!中分享您的想法。

欢迎!有关本站工作原理的更多信息,请查看关于页面。

0 投票
编译器

我本以为下面的两个Java互操作调用都会避免使用反射,但实际上只有第一个涉及到f1的情况会。

`
Clojure 1.6.0
user=> (set! warn-on-reflection true)
true
user=> (defn f1 ^java.util.LinkedList [coll] (java.util.LinkedList. coll))

'user/f1

user=> (def f2 (fn ^java.util.LinkedList [coll] (java.util.LinkedList. coll)))

'user/f2

user=> (.size (f1 [2 3 4]))
3
user=> (.size (f2 [2 3 4]))
反射警告,NO_SOURCE_PATH:5:1 - 无法解析对字段size的引用。
3
`

不确定这与CLJ-1232是否有关系,但这个问题在测试其变体时被发现。

8 回答

0 投票

评论者:jafingerhut

多么美的票号,1543。这是哥白尼最著名的书籍出版的年份:http://en.wikipedia.org/wiki/Nicolaus_Copernicus

0 投票

评论者:wagjo

arg vector的类型提示不应该是仅用于原始类型的提示吗?据我所知,非原始类型的提示应该放在函数名上,其他都是非习惯用法。

0 投票

评论者:bronsa

这不是关于参数向量提示与函数名提示之间的问题。
问题是返回类型提示不能放在匿名函数上,只能放在defn上,因为:arglists将自动添加到Var的字段元数据中。

这就是我为什么想把信息作为函数的字段而不是作为Var的元数据的原因之一。

0 投票

评论者:jafingerhut

Jozef,你可能说的是正确的,参数向量上的非原始类型提示非惯用。你能提供一些参考资料供我阅读吗?

0 投票

评论者:tsdh

https://clojure.org/java_interop#Java Interop-Type Hints中,只有对参数向量上的提示的版本进行了记录。但是,在你只有一个参数(或所有参数返回相同类型的值)的情况下,对var名称的提示也适用。但这两个版本似乎有不同的语义。请查看CLJ-1232。

0 投票
评论:wagjo_

类型提示是Clojure中的一个非常复杂的部分,但你几乎总是可以应用一个*place提示在符号*惯用法。对参数向量上的类型提示只有在两种情况下才能进行
- 原始提示
- 对不同参数次数具有不同的返回类

在第一种情况下,编译器需要类型提示来编译fn*(见[1]),不是后来,因此你必须指定它们在参数向量上。

第二种情况,也就是这里讨论的问题,只用于使用defn进行定义。编译器首先在var的元数据中查找标签,如果找不到,它有一个特殊的案例,在这种情况下,它在:arglist元数据中查找返回类。这显然是一个非常特殊的案例[2],用于处理您对不同参数次数有不同的返回类的情况。显然,使用def而不是defn不会为您创建:arglist元数据,因此您会看到反射警告。示例


user=> (def f2 (fn ^java.util.LinkedList [coll] (java.util.LinkedList. coll)))
#'user/f2
user=> (.size (f2 [2 3 4]))
反射警告,/tmp/form-init.clj:1:1 - 找不到字段大小。
3
user=> (alter-meta! #'f2 assoc :arglists '(^java.util.LinkedList [coll]))
{:ns #<Namespace user>, :name f2, :file "/tmp/form-init.clj", :column 1, :line 1, :arglists ([coll])}
user=> (.size (f2 [2 3 4]))
3


顺便提一下,CLJ-1491对此类主题的讨论略有相关。

【1】 https://github.com/clojure/clojure/blob/03cd9d159a2c49a21d464102bb6d6061488b4ea2/src/jvm/clojure/lang/Compiler.java#L5134
【2】 https://github.com/clojure/clojure/blob/03cd9d159a2c49a21d464102bb6d6061488b4ea2/src/jvm/clojure/lang/Compiler.java#L3572

0 投票

评论者:wagjo

Andy,我找到了一些不符合我建议的资料 :) 查看 CLJ-811 和(链接:1)。

(链接:1) https://groups.google.com/d/msg/clojure/b005zQCPxOQ/6G0AlWKKKa0J

0 投票
参考: https://clojure.atlassian.net/browse/CLJ-1543(由jafingerhut报告)
...