什么类型的功能?

时间:2010-09-14 11:43:34

标签: clojure types

让我们尝试一些对“type”函数的调用:

user=> (type 10)
java.lang.Integer

user=> (type 10.0)
java.lang.Double

user=> (type :keyword?)
clojure.lang.Keyword

现在使用匿名函数:

user=> (type #(str "wonder" "what" "this" "is"))
user$eval7$fn__8

A)这是什么意思“user $ eval7 $ fn__8”? B)以及什么类型的功能?

“类型”的来源是:

user=> (source type)
(defn type
  "Returns the :type metadata of x, or its Class if none"
  {:added "1.0"}
  [x]
  (or (:type (meta x)) (class x)))
nil

所以函数需要具有元数据的特定部分或者是类

检查匿名函数的元数会产生nada:

user=> (meta #(str "wonder" "what" "this" "is"))
nil

尝试不同的方法:

user=> (defn woot [] (str "wonder" "what" "this" "is"))
#'user/woot
user=> (meta woot)
{:ns #<Namespace user>, :name woot}

C)似乎有一些元,但我认为这是符号“woot”的元,对吧?

“或”的后半部分:

user=> (class #(str "wonder" "what" "this" "is"))
user$eval31$fn__32

user=> (class woot)
user$woot

这些是什么:“user $ eval31 $ fn__32”和“user $ woot”以及它们来自哪里?

签出“class”函数会产生:

user=> (source class)
(defn ^Class class
  "Returns the Class of x"
  {:added "1.0"}
  [^Object x] (if (nil? x) x (. x (getClass))))
nil

并进一步调查收益率:

user=> (.getClass #(str "wonder" "what" "this" "is"))
user$eval38$fn__39

user=> (.getClass woot)
user$woot

我不明白。 D)这是一个哈希码:eval38 $ fn__39? E)这是一个符号:woot?

F)为什么函数没有类型?它不应该是一个IFn或其他东西吗?

4 个答案:

答案 0 :(得分:19)

函数的类型为clojure.lang.IFn,它是一个Java接口。

每个Clojure函数都被编译成一个实现clojure.lang.IFn的Java类。名称user$eval7$fn__8是该类的“二进制类名称”,即其在JVM中的内部名称。

答案 1 :(得分:15)

Clojure建立在JVM上。

JVM不支持开箱即用的第一类函数或lambdas。每个Clojure函数一旦编译,就会从JVM的角度成为它自己的匿名类。从技术上讲,每个功能都是它自己的类型。

它成为实现 IFn的类,但是当你检索它的类型时,它会为你提供每次都不同的匿名类的名称。

答案 2 :(得分:3)

以下是API docs

中的说明
Returns the :type metadata of x, or its Class if none

你所看到的(“user $ eval7 $ fn__8”)是由Clojure创建的内部生成的内部类的名称,用于实现你定义的匿名函数。

您可能已经注意到,Clojure不遵循标准的Java类命名约定: - )

请注意,该类实现了接口clojure.lang.IFn - 这适用于所有Clojure函数。

答案 3 :(得分:1)

我是一个新手,但我会变得大胆。首先,我们对函数的“类型”有两个不同的含义,一个是clojure内部的java接口和类,另一个是作为编程概念的函数类型。采用第二种方法,函数的类型将是其返回值的类型(或其params类型和返回值类型):

1)我猜所有函数都实现了IFn接口,无论它们当前的类

2)如果函数是匿名或命名的,则由clojure自动生成的类名称差异,但在两种情况下似乎都是内部类(他们的名称用$分隔,从外部类到内部类)

3)如果在函数定义中对其进行注释,则返回值的类型可以位于函数元数据的:tag键中。 F.E.您公开的函数类具有Class作为其返回类型的原因,在其def中,名称前面有一个^ Class。

我假设您熟悉java(或类似的oop lang),对不起,如果不是