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 发布

参数向量上的类型提示不是只用于原始类型提示吗?据我所知,非原始类型提示应该在函数名上,其余都是非惯用性。

0

评论由:bronsa 提出

这不是关于参数向量提示与函数名提示之间的差异的问题。
这里的问题是,无法在匿名函数上放置返回类型提示,但只能在定义上放置,因为 Var 的元数据中将会添加 :arglists。

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

0

评论由:jafingerhut 发布

Jozef,你可能是正确的,参数向量上的非原始类型提示可能不符合惯例。你能提供我可以阅读的参考资料吗?

0

评论由:tsdh 提出

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

0
_评论由:wagjo 提出_

类型提示是 Clojure 的一部分,但您几乎总是可以应用一个 *'place hint on a symbol'* 习语。在参数向量上启用类型提示只有在两种情况下才需要
- 基本提示
- 不同参数个数具有不同的返回类型

在第一种情况下,编译器在编译 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 - 无法解析字段 size。
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 报告)
...