【问题标题】:Elixir - Capture value from lambdaElixir - 从 lambda 捕获值
【发布时间】:2017-09-03 21:53:04
【问题描述】:

考虑以下代码sn-p:

def capture
    Functor.function(fn(value) -> ??? end)
    ???
end
  • 假设 lambda 确实被调用了一次

捕获 lambda fn(value) 的第一个参数的首选方法是什么,它可以是 capture 方法的返回?

【问题讨论】:

  • 不确定我是否理解这个问题。你想从capture返回value吗?如果那个 fn 甚至没有被调用一次怎么办?如果该 fn 被多次调用怎么办?
  • @Dogbert 试图澄清您提出的问题,感谢您的反馈!喜欢你的昵称 ;)

标签: elixir


【解决方案1】:

这里需要某种形式的可变状态。最简单的方法是使用Agent

defmodule Functor do
  def function(f) do
    f.(:hey)
  end

  def capture do
    {:ok, agent} = Agent.start_link(fn -> nil end)
    Functor.function(fn(value) ->
      Agent.update(agent, fn _ -> value end)
    end)
    Agent.get(agent, &(&1))
  end
end

IO.inspect Functor.capture()

输出:

:hey

注意事项:

如果 fn 从未被调用,您将获得代理的初始值(上面代码中的nil)。

如果 fn 被多次调用,您将获得最后一次调用的值。稍作修改,您甚至可以捕获 所有 值,如果这是您想要的。


编辑:由于您提到您仅将其用于测试,因此还有另一种更简洁的方法。从 fn 向自己发送一条消息并使用assert_receive 断言:

test "the truth" do
  pid = self()
  Functor.function(&send(pid, &1))
  assert_receive :hey
end

【讨论】:

  • 感谢您的精彩回答!我已经在使用代理,但想确定首选的方法。我们目前仅将这种技术用于编写单元测试 - 据我了解,我们很少在生产中使用它。
  • 如果这只是为了测试,请查看我的编辑以获得更好/更短的方法!
  • 感谢您的更新,确实对于简单的情况,assert_receive 将是首选解决方案。 ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多