【问题标题】:How to cast string to boolean in Clojure如何在 Clojure 中将字符串转换为布尔值
【发布时间】:2012-08-08 06:26:27
【问题描述】:

我有以下陈述

(if "true"  (println "working") (println "not working"))

结果是 - 工作

(if "false"  (println "working") (println "not working"))

结果是 - 工作

两个时间的结果是一样的,我怎样才能正确地将字符串转换为 clojure 中的布尔值。

【问题讨论】:

    标签: string clojure boolean


    【解决方案1】:

    您可以创建一个新的 java Boolean 对象,该对象有一个接受字符串的方法。如果你然后使用 clojure 的布尔函数,你实际上可以让它在 clojure 中工作。

    (boolean (Boolean/valueOf "true")) ;;true
    (boolean (Boolean/valueOf "false")) ;;false 
    

    【讨论】:

    • 永远不要这样做。使用Boolean 构造函数总是错误的,总是;它甚至不应该存在。相反,请使用(Boolean/valueOf x)
    • 请参阅docs.oracle.com/javase/6/docs/api/java/lang/…,了解网络上关于为什么不应该这样做的众多解释之一。或谷歌java boolean constructor 来查看讨论。 edit 实际上,链接的 javadoc 暗示空间/速度是原因;你最好在谷歌上搜索一下,看看为什么它在语义上是错误的。
    • 所以在这种情况下,我假设它只是为了速度,因为它被转换为 clojure 布尔类型? (我不完全确定)
    • 好吧,既然你会立即将结果发送到clojure.core/boolean,你会没事的,因为这会强制返回一个原始布尔值(可能带有反射)。但是您不应该这样做的原因是,在任何代码中看到(Boolean. x) 都会在您的脑海中敲响巨大的警钟。您想阅读您的代码,而不必每次都关闭警钟,对吗? :)
    • @Mars 这些 cmets 中的讨论主要是关于答案的早期版本,(Boolean. x)。它现在已经过时了,但我认为值得作为 PSA 离开,以防万一有人写 (Boolean. x) 碰巧看到这个并了解为什么不这样做。
    【解决方案2】:

    如果您必须将字符串视为布尔值,read-string 是一个合理的选择。但是,如果您知道输入将是一个格式良好的布尔值(即“true”或“false”),您可以将集合 #{"true"} 用作函数:

    (def truthy? #{"true"})
    (if (truthy? x)
      ...)
    

    或者,如果您想将除“false”之外的任何字符串视为真实(大致是 Clojure 如何看待任何事物的真实性),您可以使用(complement #{"false"})

    (def truthy? (complement #{"false"}))
    (if (truthy? x)
      ...)
    

    如果你想做一些像 PHP 的弱类型转换这样卑鄙的事情,你必须自己编写规则。

    【讨论】:

    • 当您可以使用= 时,为什么还要设置方式?例如:(def truthy? (partial = "true"))
    • 如果您想知道这是如何工作的,sethash-maps 是函数,它与返回值的 (get #{"true" "d"} "true") 具有相同的功能,如果它存在于集合中,则返回nil。你可以在这里阅读更多:blog.jayfields.com/2010/08/clojure-using-sets-and-maps-as.html
    • 既然可以只使用一组,为什么还要使用partial =
    【解决方案3】:

    使用read-string

    (if (read-string "false")  (println "working") (println "not working"))
    

    【讨论】:

    • 这个建议似乎很有效。对于 ClojureScript,它是 (cljs.reader/read-string ...)
    【解决方案4】:

    您应该始终考虑包装代码以将这种转换为明确命名的函数。这使您可以在代码中更具描述性,并且还允许您在以后需要时更改实现(例如,如果您确定其他字符串也应该被视为真实)。

    我建议如下:

    (defn true-string? [s]
      (= s "true"))
    

    将此应用于您的测试用例:

    (if (true-string? "true")   (println "working") (println "not working"))
    => working
    
    (if (true-string? "false")  (println "working") (println "not working"))
    => not working
    

    【讨论】:

      猜你喜欢
      • 2011-02-17
      • 2012-04-02
      • 2021-02-23
      • 1970-01-01
      • 1970-01-01
      • 2018-09-07
      • 1970-01-01
      • 2010-09-20
      相关资源
      最近更新 更多