2012-08-08 14 views
5

Mam następujące stwierdzeniaJak oddać ciąg Boolean w Clojure

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

wynik jest - praca

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

wynik jest - praca

Zarówno wynik czas jest taki sam, jaki można Odpowiednio rzuciłem string na boolean w clojure.

Odpowiedz

2

Korzystanie read-string

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

Można utworzyć nowy obiekt Boolean java, który ma metodę, która akceptuje ciąg. Jeśli następnie użyjesz funkcji boolean clojure, możesz faktycznie działać w trybie clojure.

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

* * Nigdy tego zrobić. Używanie konstruktora 'Boolean' jest zawsze błędem, zawsze; to nie powinno nawet istnieć. Zamiast tego użyj '(Boolean/valueOf x)'. – amalloy

+0

Co masz na myśli, że zawsze jest to błąd? – smunk

+3

Zobacz http://docs.oracle.com/javase/6/docs/api/java/lang/Boolean.html#Boolean(boolean) dla jednego z wielu objaśnień w Internecie, dlaczego nie powinieneś tego robić. Lub google dla 'java boolean constructor', aby zobaczyć dyskusję. ** edit ** W rzeczywistości połączone javadoc oznacza, że ​​przyczyną jest przestrzeń/prędkość; lepiej się wylogować i zobaczyć, dlaczego jest to semantycznie błędne. – amalloy

11

Jeśli trzeba traktować jako wartości logiczne ciągi, read-string jest rozsądnym wyborem. Ale czy wiesz, że wejście będzie dobrze uformowane logiczna (czyli albo „prawda” lub „fałsz”), można po prostu użyć użyć zestawu #{"true"} jako funkcję:

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

Albo, jeśli chcesz traktować dowolny ciąg, ale „false” jako truthy (z grubsza jak Clojure postrzega truthiness na cokolwiek), można użyć (complement #{"false"}):

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

Jeśli chcesz zrobić coś tak podłego jak konwersje słabego typowania PHP jest, będziesz sam musisz napisać zasady.

+2

Dlaczego idź, gdy możesz po prostu użyć '='? Np .: '(def truthy? (Partial =" true "))' – Ankur

+3

Zestawy są po prostu chłodniejsze. Nie ma lepszego powodu. – amalloy

2

Zawsze powinieneś pomyśleć o zawijaniu kodu, aby dokonać tego rodzaju konwersji w wyraźnie nazwaną funkcję. Dzięki temu możesz być bardziej opisowy w swoim kodzie, a także możesz zmienić implementację, jeśli zajdzie taka potrzeba, w późniejszym terminie (np. Jeśli identyfikujesz inne ciągi, które również powinny być liczone jako prawda).

sugeruję coś takiego:

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

Stosując to do przypadków testowych:

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

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