Elixir 如何测试函数保护子句中的结构值?

Elixir 如何测试函数保护子句中的结构值?,elixir,phoenix-framework,Elixir,Phoenix Framework,在Phoenix/Elixir应用程序中,在这个小小的卫生功能中,当用户没有输入电子邮件时,我遇到了一个问题 我正在使用结构来处理数据。还有一个简单的函数,它(目前)只需去除空白并更新结构(map)。到目前为止,它工作得很好,但是当字段email为nil时,我得到一个错误 **(FunctionClauseError)String.Unicode.strip/1中没有匹配的函数子句 因此,我引入了一个guard子句来检查这种情况,然后只对用户名进行清理 defmodule MyApp.User

在Phoenix/Elixir应用程序中,在这个小小的卫生功能中,当用户没有输入电子邮件时,我遇到了一个问题

我正在使用结构来处理数据。还有一个简单的函数,它(目前)只需去除空白并更新结构(map)。到目前为止,它工作得很好,但是当字段
email
nil
时,我得到一个错误

**(FunctionClauseError)String.Unicode.strip/1中没有匹配的函数子句
因此,我引入了一个guard子句来检查这种情况,然后只对用户名进行清理

defmodule MyApp.User do
defstruct用户名:nil,电子邮件:nil,密码:nil,哈希密码:nil
#无保护子句的消毒输入
def消毒用户(用户)do
%{user |用户名:String.strip(user.username),电子邮件:String.strip(user.email)}
结束
#带保护子句的消毒输入
def sanitize_user(user)何时为_nil(user.email)do
%{user | username:String.strip(user.username)}
结束
def sanitize_用户(用户)何时执行_二进制(user.email)操作
%{user |用户名:String.strip(user.username),电子邮件:String.strip(user.email)}
结束
结束
现在我在编译时遇到一个错误:

**(CompileError)web/models/user.ex:54:无法调用远程函数Access.get/2内部保护
我猜这是因为这个字段的值在编译时不可用。或者类似的


如何解决这个问题?如何在guard子句中测试结构的值?

您关于值在编译时不可用的假设是正确的。但是,您可以将模式与地图中的值进行匹配,并在防护中使用它们

您可以编写如下函数:

  def sanitize_user(%MyApp.User{email: nil} = user) do
    %{user | username: String.strip(user.username)}
  end
  def sanitize_user(%MyApp.User{email: email} = user) when is_binary(email) do
    %{user | username: String.strip(user.username), email: String.strip(user.email)}
  end
如果要允许传递其他结构(在本例中不太可能),也可以在没有用户结构的映射上进行匹配:

  def sanitize_user(%{email: nil} = user)

谢谢这就解决了问题。顺便说一句,您在第二个函数定义(第一个解决方案)中有一个输入错误。有一个漏洞(太多了。很好。我已经纠正了错误。:@OleSpaarmann:如果Gazler把这个答案标记为已解决,那就更好了。