日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
繼續(xù)探索with語(yǔ)句的奇妙之處

在上一篇博客《漂亮的with,魚與熊掌可以兼得》中,展現(xiàn)了with的優(yōu)雅之處,然而在比較with與|>時(shí),言猶未盡,講得不夠透徹。

成都創(chuàng)新互聯(lián)于2013年創(chuàng)立,先為東坡等服務(wù)建站,東坡等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為東坡企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。

在那篇博客中,我說(shuō):

  • 畢竟with/1并不是try/catch,它并不能捕獲執(zhí)行中拋出的錯(cuò)誤,然后轉(zhuǎn)向else進(jìn)行錯(cuò)誤處理。只有當(dāng)模式匹配出現(xiàn)錯(cuò)誤時(shí),才會(huì)轉(zhuǎn)向else。
  • 要優(yōu)雅地處理錯(cuò)誤,并用優(yōu)雅的with/1將邏輯串聯(lián)起來(lái),就需要重構(gòu)get_user,get_response,send_response等函數(shù)。當(dāng)程序邏輯正確時(shí),返回一個(gè)tuple對(duì)象{:ok, result};如果出現(xiàn)錯(cuò)誤,則返回{:error, error}。

如果進(jìn)行了這樣的重構(gòu),是否意味著|>也可以將健壯性與優(yōu)雅結(jié)合起來(lái)呢?因?yàn)樵贓lixir中,函數(shù)的定義使用了模式匹配,因此,在定義參與|>操作的函數(shù)時(shí),可以通過(guò)模式匹配來(lái)考慮各種情況,這其中可以包含對(duì){:error, error}情形的處理,使得數(shù)據(jù)流不至于在流經(jīng)該函數(shù)時(shí)因?yàn)殄e(cuò)誤而崩潰掉。

Joseph Kain在博客Learning Elixir's with給出了一個(gè)例子,執(zhí)行了ecto查詢:

 
 
 
  1. defp results(conn, search_params) do 
  2.     conn.assigns.current_user 
  3.     |> Role.scope(can_view: Service) 
  4.     |> within(search_params) 
  5.     |> all 
  6.     |> preload(:user) 
  7. end 
  8.  
  9. defp within(query, %{"distance" => ""}), do: {:ok, query} 
  10. defp within(query, %{"distance" => x, "location" => l} do 
  11.     {dist, _} = Float.parse(x) 
  12.     Service.within(query, dist, :miles, l) 
  13. end  
  14. defp within(query, _), do: {:ok, query} 
  15.  
  16. defp all({:error, _} = result), do: result 
  17. defp all({:ok, query}), do: {:ok, Repo.all(query)} 
  18.  
  19. defp preload({:error, _} = result), do: result 
  20. defp preload({:ok, enum}, field) do 
  21.     {:ok, Repo.preload(enum, field)} 
  22. end 

且不管業(yè)務(wù),我們可以清晰地看到在all與preload函數(shù)增加了對(duì){:error, _}分支的處理,這樣就可以避免數(shù)據(jù)流動(dòng)的管道不至于因?yàn)殄e(cuò)誤而終止。

如果使用with,雖然結(jié)構(gòu)不如|>清晰直觀,卻可以避免在all與preload中去處理錯(cuò)誤分支。因?yàn)閣ith語(yǔ)句同樣使用了模式匹配,只要參與的方法不能滿足模式匹配的條件,就不會(huì)再執(zhí)行do,從而規(guī)避了錯(cuò)誤引起的終止:

 
 
 
  1. defp results(conn, search_params) do 
  2.     with user <- conn.assigns.current_user, 
  3.          query <- Role.scope(user, can_view: Service), 
  4.          {:ok, query} <- within(query, search_params), 
  5.          query <- all(query), 
  6.     do: {:ok, preload(query, :user)} 
  7. end 
  8.  
  9. defp within(query, %{"distance" => ""}), do: {:ok, query} 
  10. defp within(query, %{"distance" => x, "location" => l} do 
  11.     {dist, _} = Float.parse(x) 
  12.     Service.within(query, dist, :miles, l) 
  13. end defp within(query, _), do: {:ok, query} 
  14.  
  15. defp all(query), do: Repo.all(query) 
  16.  
  17. defp preload(enum, field) do: {:ok, Repo.preload(enum, field)} 

由于all/1與preload/2僅僅是對(duì)Repo.all/1與Repo.preload/2的簡(jiǎn)單封裝,所以可以進(jìn)一步簡(jiǎn)化代碼:

 
 
 
  1. defp results(conn, search_params) do 
  2.     with user <- conn.assigns.current_user, 
  3.          query <- Role.scope(user, can_view: Service), 
  4.          {:ok, query} <- within(query, search_params), 
  5.          query <- Repo.all(query), 
  6.   do: {:ok, Repo.preload(query, :user)} 
  7. end 

多余的代碼被有效地清除了,而功能與健壯性并沒(méi)有得到任何降低。這是within的奇妙之處。

【本文為專欄作者“張逸”原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】


網(wǎng)頁(yè)標(biāo)題:繼續(xù)探索with語(yǔ)句的奇妙之處
文章路徑:http://www.dlmjj.cn/article/cdseooj.html