【问题标题】:Backporting Sigils and make it work with variables向后移植 Sigils 并使其与变量一起使用
【发布时间】:2019-03-06 18:12:31
【问题描述】:

所以我刚开始使用 Elixir,发现当前的 master 添加了对 ~U[2015-01-13 13:00:07Z] sigil 的支持以创建/解析 UTC 日期。

代码如下:

defmodule MySigils do
  defmacro sigil_U(datetime_string, modifiers)

  defmacro sigil_U({:<<>>, _, [string]}, []) do
    Macro.escape(datetime_from_utc_iso8601!(string))
  end

  defp datetime_from_utc_iso8601!(string) do
    case DateTime.from_iso8601(string) do
      {:ok, utc_datetime, 0} ->
        utc_datetime

      {:ok, _datetime, _offset} ->
        raise ArgumentError,
              "cannot parse #{inspect(string)} as UTC datetime, reason: :non_utc_offset"

      {:error, reason} ->
        raise ArgumentError,
              "cannot parse #{inspect(string)} as UTC datetime, reason: #{inspect(reason)}"
    end
  end
end

在我的代码中,我尝试将其与变量 timestamp 一起使用

timestamp = Map.get(item, "timestamp")
~U[timestamp]
** (ArgumentError) cannot parse "timestamp" as UTC datetime, reason: :invalid_format

timestamp 被解释为原样,而不是之前的匹配。

有没有办法让它工作?我需要引用/取消引用某些内容吗?除了直接使用DateTime.from_iso8601/1

【问题讨论】:

    标签: elixir sigils


    【解决方案1】:

    印记分隔符之间的所有内容都作为字符串发送。所以timestamp 变量作为字符串"timestamp" 发送到sigil_U。有一些允许插值的符号,按照惯例是小写的。例如~r~R

    iex(1)> x = "foo"
    "foo"
    
    iex(2)> ~R/#{x}/
    ~r/\#{x}/
    
    iex(3)> ~r/#{x}/
    ~r/foo/
    

    但在这种情况下,没有定义 sigil_U 的小写版本,因此您无法插入 timestamp

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多