Clojure对字符串的"应用"功能

Chr*_*ris 2 string clojure

clojure.core/apply
([f args] [f x args] [f x y args] [f x y z args] [f a b c d & args])
  Applies fn f to the argument list formed by prepending intervening arguments to args.

user=> (apply str (reverse "racecar"))
"racecar"
user=> (str (reverse "racecar"))
"(\\r \\a \\c \\e \\c \\a \\r)"
Run Code Online (Sandbox Code Playgroud)

我不明白这种行为是如何与文档一致的.我错过了什么?

Dao*_*Wen 7

你的问题不是很清楚.我假设你对返回类型感到困惑reverse.

reverse函数返回一个序列,而不是一个字符串.如果在字符串上调用reverse,它会将其视为一个字符序列,从而返回相反的字符序列.

apply函数允许您获取一系列参数并"解包"它们,以便您可以将它们作为位置参数直接传递给函数.例如,(apply f [a b c])相当于(f a b c).

正如我已经提到的,Clojure认为字符串是characers的序列; 因此,(apply str "racecar")是相同的(apply str '(\r \a \c \e \c \a \r)),它是相同的(str \r \a \c \e \c \a \r).因此,当您调用apply str该字符序列时,它会将所有字符连接成一个新字符串 - 这正是我所期望的基于文档的内容.

如果您只想反转字符串而不需要apply str获取字符串结果,则应使用clojure.string/reverse而不是clojure.core/reverse:

user=> (require '[clojure.string :as str])
nil
user=> (str/reverse "hello")
"olleh"
Run Code Online (Sandbox Code Playgroud)

  • @Chris - FYI,在Lisps中使用前缀表示法的一个好处是像`<=`这样的函数不会被强制为二进制.您可以利用这一事实来简化过滤器功能:`#(<= 65(int%)90)`.当然,这可能更简单,更清晰:`#(Character/isUpperCase%)`.请注意,Java方法不是Clojure函数,因此您仍然需要在函数中包含对"Character/isUpperCase"的调用. (2认同)