成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

繼續探索with語句的奇妙之處

開發 開發工具
在上一篇博客《漂亮的with,魚與熊掌可以兼得》中,展現了with的優雅之處,然而在比較with與|>時,言猶未盡,講得不夠透徹。本文我們繼續探索with語句的奇妙之處。

[[189165]]

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

在那篇博客中,我說:

  • 畢竟with/1并不是try/catch,它并不能捕獲執行中拋出的錯誤,然后轉向else進行錯誤處理。只有當模式匹配出現錯誤時,才會轉向else。
  • 要優雅地處理錯誤,并用優雅的with/1將邏輯串聯起來,就需要重構get_user,get_response,send_response等函數。當程序邏輯正確時,返回一個tuple對象{:ok, result};如果出現錯誤,則返回{:error, error}。

如果進行了這樣的重構,是否意味著|>也可以將健壯性與優雅結合起來呢?因為在Elixir中,函數的定義使用了模式匹配,因此,在定義參與|>操作的函數時,可以通過模式匹配來考慮各種情況,這其中可以包含對{:error, error}情形的處理,使得數據流不至于在流經該函數時因為錯誤而崩潰掉。

Joseph Kain在博客Learning Elixir's with給出了一個例子,執行了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 

且不管業務,我們可以清晰地看到在all與preload函數增加了對{:error, _}分支的處理,這樣就可以避免數據流動的管道不至于因為錯誤而終止。

如果使用with,雖然結構不如|>清晰直觀,卻可以避免在all與preload中去處理錯誤分支。因為with語句同樣使用了模式匹配,只要參與的方法不能滿足模式匹配的條件,就不會再執行do,從而規避了錯誤引起的終止:

  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僅僅是對Repo.all/1與Repo.preload/2的簡單封裝,所以可以進一步簡化代碼:

  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 

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

【本文為51CTO專欄作者“張逸”原創稿件,轉載請聯系原作者】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2010-01-12 10:45:42

C++教程

2013-04-16 14:42:38

云計算智能手機移動通信網絡

2024-02-26 18:23:29

C++封裝代碼

2025-02-27 08:00:00

DeepSeek大模型人工智能

2017-01-19 17:54:31

曙光服務器

2024-04-03 09:43:06

C++編程代碼

2011-08-02 13:04:40

SQL Server

2025-05-15 07:15:39

2025-03-06 00:38:08

C#人工智能AI

2024-02-22 10:36:13

SELECT 語句PostgreSQL數據查詢

2024-01-29 16:55:38

C++引用開發

2018-11-02 16:16:41

程序硬盤存儲

2009-10-26 15:26:37

VB.NET屬性

2024-03-15 15:03:23

2012-04-16 09:16:48

2025-05-26 08:24:45

2010-01-14 18:02:05

C++語言

2010-03-16 13:20:18

Python pyli

2011-05-24 13:33:45

2019-04-28 11:11:26

沙箱網絡攻擊網絡安全
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩成人网 | 久久久国产精品视频 | 精品毛片 | 国产亚洲欧美在线 | 在线免费av观看 | 国产十日韩十欧美 | 国产欧美一区二区三区在线看 | 久热精品在线播放 | 九九免费视频 | 中文在线日韩 | 午夜精品久久久 | 91精品国产高清久久久久久久久 | 欧美一级做a爰片免费视频 国产美女特级嫩嫩嫩bbb片 | 成人免费区一区二区三区 | 天天看片天天干 | 97人澡人人添人人爽欧美 | 天天综合成人网 | 久久亚洲一区二区三区四区 | 欧美成人第一页 | 一区二区视频在线观看 | 亚洲成人免费电影 | 91.com在线观看 | 欧美一区二区免费电影 | 国产超碰人人爽人人做人人爱 | 国产精品久久久久免费 | 亚洲精品女人久久久 | 亚洲国产精品久久久久秋霞不卡 | 亚洲欧洲在线视频 | 亚洲欧美日韩精品久久亚洲区 | 91爱啪啪| 污片在线观看 | 欧美成人精品一区二区男人看 | 中文字幕视频免费 | 国产精品久久久免费 | 欧美日本久久 | 欧美日本韩国一区二区 | 美女爽到呻吟久久久久 | 黄色片av | 不卡一区二区三区四区 | 成人免费在线播放视频 | 国产精品久久久一区二区三区 |