【问题标题】:Why does my clojure REPL output gibberish?为什么我的 clojure REPL 输出乱码?
【发布时间】:2019-12-20 11:04:02
【问题描述】:

我正在对一些非常基本的功能进行原型设计,但 REPL 输出的是完全随机的东西。

只是尝试编写一个函数来更新地图中的值会得到以下结果:

fwd.core=> (fn [step] (update {:x 10 :y 10} :x 20) 20)
#object[fwd.core$eval1593$fn__1594 0x3d2da438 "fwd.core$eval1593$fn__1594@3d2da438"]

【问题讨论】:

  • 这基本上是 jvm 看到的那个函数“对象”中的 .toString
  • 啊,我明白了,我在那里搞砸了我的函数定义。但是这些错误信息真的很糟糕……
  • 这不是错误消息,它是代表该函数对象的字符串。您的代码是一个完全有效的函数。读心术超出了大多数编译器的范围。
  • 这不是“错误”——你在那里显示的代码是合法的,这是你的功能的字符串表示——而在我的 repl 中,我得到了一个更短的名称(也许它随着 1.10 而你在一些旧版本上?)。如果您想为该 anon-fn 取一个“更好”的名称,您可以将其命名为:(fn my-fun [step] ...)
  • 我正在努力学习这个。但是感谢您解决这个问题!

标签: clojure read-eval-print-loop


【解决方案1】:

函数是 Clojure 中的一等公民。所以你定义了一个匿名函数(请注意,这里接近于无操作,因为你没有坚持它——而且你在错误的地方也有一些括号(见下文))和 REP我为你打印了。

所以这基本上是 JVM 看到的函数对象的 .toString() 表示。

旁注:

为了更好地命名您的堆栈跟踪,您还可以将匿名 fns 命名为:

user=> (fn [step] (update {:x 10 :y 10} :x 20) 20)
#<Fn@559d19c user/eval8096[fn]>
user=> (fn my-fancy-name [step] (update {:x 10 :y 10} :x 20) 20)
#<Fn@451816fd user/eval8105[my_fancy_name]>

编辑(函数存在多个问题)

至于函数本身,内部更新也是无操作的,因为你 也没有分配更新的结果。该功能现在总是 返回20

要调用该函数,您必须修复括号:

user=> ((fn [step] (update {:x 10 :y 10} :x step)) 20)
Execution error (ClassCastException) at user/eval8105$fn (REPL:1).
java.lang.Long cannot be cast to clojure.lang.IFn

(该函数首先针对周围的括号,所以它 将被调用。

这现在给出一个错误,因为 update 需要一个函数 - 使用 assoc 而是:

user=> ((fn [step] (assoc {:x 10 :y 10} :x step)) 20)
{:x 20, :y 10}

【讨论】:

  • 我试图在那里应用 20 作为参数。不太明白这里发生了什么。这不是抱怨,这是肯定的。
  • @Alper 啊,现在我明白了你的困惑——函数本身看起来很奇怪(没有冒犯),所以我认为你只是将一些表单拼凑在一起,而仅仅因为输出而感到困惑。我已经添加了一些关于其他问题的更多解释。
  • 超级骗子!这里有点入口,但看起来很容易管理。
猜你喜欢
  • 2021-11-15
  • 1970-01-01
  • 2010-09-07
  • 1970-01-01
  • 1970-01-01
  • 2012-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多