我试图将字符串解析为浮点数时遇到此错误:
case insert_product_shop(conn, existing_product.id, existing_shop.id, String.to_float(posted_product["price"])) do
错误:
20:45:29.766 [error] #PID<0.342.0> running Api.Router terminated
Server: 172.20.10.2:4000 (http)
Request: POST /products
** (exit) an exception was raised:
** (ArgumentError) argument error
:erlang.binary_to_float(58.25)
(api) lib/api/router.ex:120: anonymous fn/1 in Api.Router.do_match/4
(api) lib/api/router.ex:1: Api.Router.plug_builder_call/2
(api) lib/plug/debugger.ex:123: Api.Router.call/2
(plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
(cowboy) /Users/Ben/Development/Projects/vepo/api/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.exe
cute/4
当我改为
时case insert_product_shop(conn, existing_product.id, existing_shop.id, Float.parse(posted_product["price"])) do
:
我明白了:
20:54:12.769 [error] #PID<0.336.0> running Api.Router terminated
Server: 172.20.10.2:4000 (http)
Request: POST /products
** (exit) an exception was raised:
** (ArgumentError) argument error
:erlang.binary_to_float(24)
(api) lib/api/router.ex:82: anonymous fn/1 in Api.Router.do_match/4
(api) lib/api/router.ex:1: Api.Router.plug_builder_call/2
(api) lib/plug/debugger.ex:123: Api.Router.call/2
(plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
(cowboy) /Users/Ben/Development/Projects/vepo/api/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.exe
cute/4
如何从字符串正确解析为float?我是否也可以允许它为字符串或浮点数,如果是字符串,则解析为浮点数?
答案 0 :(得分:4)
根据错误,看起来输入已经是Float
。
** (ArgumentError) argument error
:erlang.binary_to_float(58.25)
事实上,如果输入不是String.to_float/1
,则String
会引发错误。
iex(1)> String.to_float(58.25)
** (ArgumentError) argument error
:erlang.binary_to_float(58.25)
iex(1)> String.to_float("58.25")
58.25
另请注意,如果输入没有小数位,String.to_float/1
也会抱怨。
iex(2)> String.to_float("58")
** (ArgumentError) argument error
:erlang.binary_to_float("58")
iex(2)> String.to_float("58.0")
58.0
您需要编写自定义函数。我不确定posted_product["price"]
的来源,以及您是否希望它有不同的输入类型。这可能是一个错误。
一种可能的解决方法是始终将输入转换为String
,并使用Float.parse/1
iex(12)> {f, _} = Float.parse(to_string("58.0"))
{58.0, ""}
iex(13)> f
58.0
iex(14)> {f, _} = Float.parse(to_string(58.0))
{58.0, ""}
iex(15)> f
58.0
请注意,Float.parse/1
可能会返回:error
,因此您必须处理该问题。
另一个可能稍微提高效率的选项是仅在必要时使用is_float/1
和is_string/1
来处理转化。
defmodule Price do
def to_float(input) when is_float(input) do
input
end
def to_float(input) do
case Float.parse(to_string(input)) do
{f, ""} -> f
_ -> :error
end
end
end
iex(2)> Price.to_float(32)
32.0
iex(3)> Price.to_float(32.0)
32.0
iex(4)> Price.to_float("32")
32.0