如何使用ClojureScript从本地存储中提取整数并将其强制转换为整数?

12

我正在尝试从localStorage中提取一个整数,用于一个简单的ClojureScript应用程序。我尝试过的所有方法都出现了某种错误行为。

以下是我的程序,没有从本地存储初始化。我将忽略未找到键的情况,因为我有一个处理这个情况的JQuery版本来初始化存储。此外,JQuery应用程序可以很好地读取保存在localStorage中的ClojureScript数据。所以对我来说这是有效的。

简要总结如下。消息显示“自上次事件以来已经过去了$number天”,其中$number在名为“counter”的div中。我有三个按钮:一个增加计数,一个减少计数,最后一个将计数重置为零。

 (ns days.core
        (:require [goog.events :as events]
                  [goog.string :as string]
                  [goog.math.Integer :as int]
                  [goog.dom :as dom]))
    (defn initial-state [] 0)
    (def count (atom (initial-state)))
    (defn set-counter [n]
       (do (.setItem (.localStorage (dom/getWindow)) "count" n)
           (dom/setTextContent (dom/getElement "counter") n)))
    (defn set-button-fn [button-id f-update]
       (events/listen (dom/getElement button-id)
                      "click"
                      (fn [] (do (f-update) (set-counter @count)))))
    (defn start-app []
       (do
           (set-counter @count)
           (set-button-fn "addDay" (fn [] (swap! count inc)))
           (set-button-fn "decDay" (fn [] (swap! count dec)))
           (set-button-fn "reset" (fn [] (reset! count 0)))))
    (start-app)
当我尝试使用goog.math.Integer.fromString()进行整型转换时,调用inc会在末尾添加1(7变成71和711)。而调用dec则会按预期对其进行递减(711变成710和709)。以下是我的初始化方式。
(defn initial-state []
  (integer/fromString (.getItem (.localStorage (dom/getWindow)) "count")))

我意识到这是一个goog.math.Integer对象,所以我尝试在它上面调用.toNumber()方法。但是,这和.toInt()方法似乎给了我一个函数。function (){if(this.e==-1)return-w(this).D();else{for(var a=0,b=1,d=0;d<0?e:Ua+e)b*=Ua,this.a[d]+=c*b,c=this.a[d]+a,a=w(c/Ua),this.a[d]=c-Ua*a,d++;0==this.a[this.e-1]&&this.e>1;this.e--)this.a.pop()}

(defn initial-state [] (.toNumber 
  (integer/fromString (.getItem (.localStorage (dom/getWindow)) "count"))))

Clojure似乎使用Java的Integer类将字符串转换为整数,甚至到了(int "1")抛出异常的地步,所以这个想法被否决了。

我还尝试调用JavaScript的parseInt()。这是我在JQuery版本中的写法。但是ClojureScript调用总是返回1,即使我的JQuery版本在Chrome开发者工具中显示存储了8。

(defn initial-state []
  (.parseInt (dom/getWindow)
             (.getItem (.localStorage (dom/getWindow)) "count")))
任何想法如何让这个字符串值像整数一样运行?这一定很简单,但我一无所获。
3个回答

35

您可以通过 js 命名空间访问 parseInt 函数,如下所示:

(js/parseInt "7")

1
为什么要在“7”上调用str函数? - pupeno
2
我看到了这个答案并尝试了一下。我意识到,(js/parseInt "7abc")也会返回7。该死的JavaScript,你为什么要这样做?... - n2o
很好,对我来说这个行为大多数情况下都是好的。当不是这样时我会使用 (defn str->int [s] (when (= s (str (js/parseInt s))) (js/parseInt s))) 或者 (defn str->int [s] (if (= s (str (js/parseInt s))) (js/parseInt s) s)) - Jp_

2

以下是一种在Clojure和ClojureScript中均可使用的方法:

(defn- str->int [s]
  #?(:clj (Integer/parseInt s)
     :cljs (js/parseInt s)))

(str->int "10")
> 10

这篇文章应该获得更多的赞! :) - Josh Glover

0

ClojureScript的方式:

(ns reader-test.core
    (:require [cljs.reader :as reader]))

(reader/read-string "7") ;; 7 - integer
(reader/read-string "1.3") ;; 1.3 - non-integer number

这不仅适用于整数,而且适用于任何类型。


1
请确保不要对不受信任的数据使用read-string函数:https://groups.google.com/forum/#!topic/clojure/YBkUaIaRaow - bmaddy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接