在上一篇博客《漂亮的with,鱼与熊掌可以兼得》中,展现了with的优雅之处,然而在比较with与|>时,言犹未尽,讲得不够透彻。
成都创新互联于2013年创立,先为东坡等服务建站,东坡等地企业,进行企业商务咨询服务。为东坡企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
在那篇博客中,我说:
如果进行了这样的重构,是否意味着|>也可以将健壮性与优雅结合起来呢?因为在Elixir中,函数的定义使用了模式匹配,因此,在定义参与|>操作的函数时,可以通过模式匹配来考虑各种情况,这其中可以包含对{:error, error}情形的处理,使得数据流不至于在流经该函数时因为错误而崩溃掉。
Joseph Kain在博客Learning Elixir's with给出了一个例子,执行了ecto查询:
- defp results(conn, search_params) do
- conn.assigns.current_user
- |> Role.scope(can_view: Service)
- |> within(search_params)
- |> all
- |> preload(:user)
- end
- defp within(query, %{"distance" => ""}), do: {:ok, query}
- defp within(query, %{"distance" => x, "location" => l} do
- {dist, _} = Float.parse(x)
- Service.within(query, dist, :miles, l)
- end
- defp within(query, _), do: {:ok, query}
- defp all({:error, _} = result), do: result
- defp all({:ok, query}), do: {:ok, Repo.all(query)}
- defp preload({:error, _} = result), do: result
- defp preload({:ok, enum}, field) do
- {:ok, Repo.preload(enum, field)}
- end
且不管业务,我们可以清晰地看到在all与preload函数增加了对{:error, _}分支的处理,这样就可以避免数据流动的管道不至于因为错误而终止。
如果使用with,虽然结构不如|>清晰直观,却可以避免在all与preload中去处理错误分支。因为with语句同样使用了模式匹配,只要参与的方法不能满足模式匹配的条件,就不会再执行do,从而规避了错误引起的终止:
- defp results(conn, search_params) do
- with user <- conn.assigns.current_user,
- query <- Role.scope(user, can_view: Service),
- {:ok, query} <- within(query, search_params),
- query <- all(query),
- do: {:ok, preload(query, :user)}
- end
- defp within(query, %{"distance" => ""}), do: {:ok, query}
- defp within(query, %{"distance" => x, "location" => l} do
- {dist, _} = Float.parse(x)
- Service.within(query, dist, :miles, l)
- end defp within(query, _), do: {:ok, query}
- defp all(query), do: Repo.all(query)
- defp preload(enum, field) do: {:ok, Repo.preload(enum, field)}
由于all/1与preload/2仅仅是对Repo.all/1与Repo.preload/2的简单封装,所以可以进一步简化代码:
- defp results(conn, search_params) do
- with user <- conn.assigns.current_user,
- query <- Role.scope(user, can_view: Service),
- {:ok, query} <- within(query, search_params),
- query <- Repo.all(query),
- do: {:ok, Repo.preload(query, :user)}
- end
多余的代码被有效地清除了,而功能与健壮性并没有得到任何降低。这是within的奇妙之处。
【本文为专栏作者“张逸”原创稿件,转载请联系原作者】
本文名称:继续探索with语句的奇妙之处
网页链接:http://www.shufengxianlan.com/qtweb/news40/271690.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联