精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

C# Actor的尷尬與F#美麗外表下的遺憾

開發 開發工具
本文從Erlang的Tag Message開始,講述C# Actor中存在的一些問題。最后作者又提到了F#的模式匹配,以及F#中存在的問題。

上一篇文章中,我們簡單解讀了Erlang在執行消息時候的方式。而現在,我們就一起來看看,C# Actor究竟出現了什么樣的尷尬。此外,我還打算用F#進行補充說明,最終我們會發現,雖然F#看上去很美,但是在實際使用過程中依舊有些遺憾。

Erlang中的Tag Message

老趙在上一篇文章里提到,Erlang中有一個“約定俗成”,使用“原子(atom)”來表示這條消息“做什么”,并使用“綁定(binding)”來獲取做事情所需要的“參數”。Erlang大拿,《Programming Erlang》一書的主要譯者jackyz同學看了老趙的文章后指出,這一點在Erlang編程規范中有著明確的說法,是為“Tag Message”:

5.7 Tag messages

All messages should be tagged. This makes the order in the receive statement less important and the implementation of new messages easier.

Don’t program like this:

  1. loop(State) ->  
  2.   receive  
  3.     ...  
  4.     {Mod, Funcs, Args} -> % Don't do this 
  5.       apply(Mod, Funcs, Args},  
  6.       loop(State);  
  7.     ...  
  8.   end. 

If messages are synchronous, the return message should be tagged with a new atom, describing the returned message. Example: if the incoming message is tagged get_status_info, the returned message could be tagged status_info. One reason for choosing different tags is to make debugging easier.

This is a good solution:

  1. loop(State) ->  
  2.   receive  
  3.     ...  
  4.     {execute, Mod, Funcs, Args} -> % Use a tagged message.  
  5.       apply(Mod, Funcs, Args},  
  6.       loop(State);  
  7.     {get_status_info, From, Option} ->  
  8.       From ! {status_info, get_status_info(Option, State)},  
  9.       loop(State);      
  10.     ...  
  11.   end.  

第一段代碼使用的模式為擁有三個“綁定”的“元組”。由于Erlang的弱類型特性,任何擁有三個元素的元組都會被匹配到,這不是一個優秀的實踐。在第二個示例中,每個模式使用一個“原子”來進行約束,這樣可以獲取到相對具體的消息。為什么說“相對”?還是因為Erlang的弱類型特性,Erlang無法對From和Option提出更多的描述。同樣它也無法得知execute或get_status_info這兩個tag的來源——當然,在許多時候,它也不需要關心是誰發送給它的。

在C#中使用Tag Message

在C#中模擬Erlang里的Tag Message很簡單,其實就是把每條消息封裝為Tag和參數列表的形式。同樣的,我們使用的都是弱類型的數據——也就是object類型。如下:

  1. public class Message  
  2. {  
  3.     public object Tag { getprivate set; }  
  4.  
  5.     public ReadOnlyCollection﹤object> Arguments { getprivate set; }  
  6.  
  7.     public Message(object tag, params object[] arguments)  
  8.     {  
  9.         this.Tag = tag;  
  10.         this.Arguments = new ReadOnlyCollection﹤object>(arguments);  
  11.     }  
  12. }  

我們可以使用這種方式來實現一個乒乓測試。既然是Tag Message,那么定義一些Tag便是首要任務。Tag表示“做什么”,即消息的“功能”。在乒乓測試中,有兩種消息,共三個“含義”。Erlang使用原子作為tag,在.NET中我們自然可以使用枚舉:

  1. public enum PingMsg  
  2. {   
  3.     Finished,  
  4.     Ping  
  5. }  
  6.  
  7. public enum PongMsg  
  8. {   
  9.     Pong  
  10. }  

在這里,我們使用簡單的ActorLite進行演示(請參考ActorLite的使用方式)。因此,Ping和Pong均繼承于Actor﹤Message>類,并實現其Receive方法。

對于Ping對象來說,它會維護一個計數器。每當收到PongMsg.Pong消息后,會將計數器減1。如果計數器為0,則回復一條PingMsg.Finished消息,否則就回復一個PingMsg.Ping:

  1. public class Ping : Actor﹤Message>  
  2. {  
  3.     private int m_count;  
  4.  
  5.     public Ping(int count)  
  6.     {  
  7.         this.m_count = count;  
  8.     }  
  9.  
  10.     public void Start(Actor﹤Message> pong)  
  11.     {  
  12.         pong.Post(new Message(PingMsg.Ping, this));  
  13.     }  
  14.  
  15.     protected override void Receive(Message message)  
  16.     {  
  17.         if (message.Tag.Equals(PongMsg.Pong))  
  18.         {  
  19.             Console.WriteLine("Ping received pong");  
  20.  
  21.             var pong = message.Arguments[0] as Actor﹤Message>;  
  22.             if (--this.m_count > 0)  
  23.             {  
  24.                 pong.Post(new Message(PingMsg.Ping, this));  
  25.             }  
  26.             else 
  27.             {  
  28.                 pong.Post(new Message(PingMsg.Finished));  
  29.                 this.Exit();  
  30.             }  
  31.         }  
  32.     }  
  33. }  

對于Pong對象來說,如果接受到PingMsg.Ping消息,則回復一個PongMsg.Pong。如果接受的消息為PingMsg.Finished,便立即退出:

  1. public class Pong : Actor﹤Message>  
  2. {  
  3.     protected override void Receive(Message message)  
  4.     {  
  5.         if (message.Tag.Equals(PingMsg.Ping))  
  6.         {  
  7.             Console.WriteLine("Pong received ping");  
  8.  
  9.             var ping = message.Arguments[0] as Actor﹤Message>;  
  10.             ping.Post(new Message(PongMsg.Pong, this));  
  11.         }  
  12.         else if (message.Tag.Equals(PingMsg.Finished))  
  13.         {  
  14.             Console.WriteLine("Finished");  
  15.             this.Exit();  
  16.         }  
  17.     }  
  18. }  

啟動乒乓測試:

new Ping(5).Start(new Pong());結果如下:

Pong received ping
Ping received pong
Pong received ping
Ping received pong
Pong received ping
Ping received pong
Pong received ping
Ping received pong
Pong received ping
Ping received pong
Finished

從上述代碼中可以看出,由于沒有Erlang的模式匹配,我們必須使用if…else…的方式來判斷消息的Tag,接下來還必須使用麻煩而危險的cast操作來獲取參數。更令人尷尬的是,與Erlang相比,在C#中使用Tag Message沒有獲得任何好處。同樣是弱類型,同樣得不到靜態檢查。那么好處在哪里?至少我的確看不出來。

C# Actor,強類型與弱類型的考慮

有朋友可能會說,C#既然是一門強類型的語言,為什么要學Erlang的Tag Message?為什么不把Ping定義為Actor﹤PingMessage>,同時把Pong定義為Actor﹤PingMessage>呢?

呃……我承認,在這里使用Tag Message的確有種“畫虎不成反類犬”的味道。不過,事情也不是您想象的那么簡單。因為在實際情況中,一個Actor可能與各種外部服務打交道,它會接受到各式各樣的消息。例如,它先向Service Locator發送一個請求,用于查詢數據服務的位置,這樣它會接受到一個ServiceLocatorResponse消息。然后,它會向數據服務發送一個請求,再接受到一個DataAccessResponse消息。也就是說,很可能我們必須把每個Actor都定義為Actor﹤object>,然后對消息進行類型判斷,轉換,再加以處理。

誠然,這種方法相對于Tag Message擁有了一定的強類型優勢(如靜態檢查)。但是如果您選擇這么做,就必須為各種消息定義不同的類型,在這方面會帶來額外的開發成本。要知道,消息的數量并不等于Actor類型的數量,即使是如Ping這樣簡單的Actor,都會發送兩種不同的消息(Ping和Finished),而且每種消息擁有各自的參數。一般來說,某個Actor會接受2-3種消息都是比較正常的狀況。在面對消息類型的汪洋時,您可能就會懷念Tag Message這種做法了。到時候您可能就會發牢騷說:

“弱類型就弱類型吧,Erlang不也用的好好的么……”

F#中的模式匹配

提到模式匹配,熟悉F#的同學們可能會歡喜不已。模式匹配是F#中的重要特性,它將F#中靜態類型系統的靈活性體現地淋漓盡致。而且——它還很能節省代碼(這點在老趙以前的文章中也有所提及)。那么我們再來看一次F#在乒乓測試中的表現。

首先還是定義PingMsg和PongMsg:

  1. type PingMsg =   
  2.     | Ping of PongMsg Actor  
  3.     | Finished  
  4. and PongMsg =   
  5.     | Pong of PingMsg Actor 

這里體現了F#類型系統中的Discriminated Unions。簡單地說,它的作用是把一種類型定義為多種表現形式,這個特性在Haskell等編程語言中非常常見。Discriminated Unions非常適合模式匹配,現在的ping對象和pong對象便可定義如下(在這里還是使用了ActorLite,而不是F#標準庫中的MailboxProcessor來實現Actor模型):

  1. let (﹤﹤) (a:_ Actor) msg = a.Post msg  
  2.  
  3. let ping =  
  4.     let count = ref 5  
  5.     { new PongMsg Actor() with  
  6.         override self.Receive(message) =  
  7.             match message with  
  8.             | Pong(pong) ->  
  9.                 printfn "Ping received pong" 
  10.                 count := !count - 1  
  11.                 if (!count > 0) then  
  12.                     pong ﹤﹤ Ping(self)  
  13.                 else 
  14.                     pong ﹤﹤ Finished  
  15.                     self.Exit() }  
  16.  
  17. let pong =   
  18.     { new PingMsg Actor() with  
  19.         override self.Receive(message) =  
  20.             match message with  
  21.             | Ping(ping) ->  
  22.                 printfn "Pong received ping" 
  23.                 ping ﹤﹤ Pong(self)  
  24.             | Finished ->  
  25.                 printf "Fininshed" 
  26.                 self.Exit() }  

例如在pong對象的實現中,我們使用模式匹配,減少了不必要的類型轉換和賦值,讓代碼變得簡潔易讀。還有一點值得順帶一提,我們在F#中可以靈活的定義一個操作符的作用,在這里我們便把“﹤﹤”定義為“發送”操作,避免Post方法的顯式調用。這種做法往往可以簡化代碼,從語義上增強了代碼的可讀性。例如,我們可以這樣啟動乒乓測試:

ping ﹤﹤ Pong(pong)至于結果則與C#的例子一模一樣,就不再重復了。

F#中的弱類型消息

可是,F#的世界就真的如此美好嗎?試想,我們該如何實現一個需要接受多種不同消息的Actor對象呢?我們只能這樣做:

  1. let another =   
  2.     { new obj Actor() with  
  3.         override self.Receive(message) =  
  4.             match message with  
  5.               
  6.             | :? PingMsg as pingMsg ->  
  7.                 // sub matching  
  8.                 match pingMsg with  
  9.                 | Ping(pong) -> null |> ignore  
  10.                 | Finished -> null |> ignore  
  11.                   
  12.             | :? PongMsg as pongMsg ->  
  13.                 // sub matching  
  14.                 match pongMsg with  
  15.                 | Pong(ping) -> null |> ignore  
  16.                   
  17.             | :? (string * intas m ->  
  18.                 // sub binding  
  19.                 let (s, i) = m  
  20.                 null |> ignore  
  21.                   
  22.             | _ -> failwith "Unrecognized message" } 

由于我們必須使用object作為Actor接受到的消息類型,因此我們在對它作模式匹配時,只能進行參數判斷。如果您要更進一步地“挖掘”其中的數據,則很可能需要進行再一次的模式匹配(如PingMsg或PongMsg)或賦值(如string * int元組)。一旦出現這種情況,在我看來也變得不是那么理想了,我們既沒有節省代碼,也沒有讓代碼變得更為易讀。與C#相比,唯一的優勢可能就是F#中相對靈活的類型系統吧。

C# Actor不好用,F#也不行……那么我們又該怎么辦?

【編輯推薦】

  1. 看Erlang中Actor模型的執行方式和優劣
  2. Erlang面向分布與并發的編程語言
  3. Erlang十分鐘快速入門
  4. 因并發而生 因云計算而熱:Erlang專家訪談實錄
  5. 淺析Erlang分布的核心技術
責任編輯:yangsai 來源: 老趙點滴
相關推薦

2009-08-20 18:13:03

F#和C#

2010-04-07 16:51:59

F#

2010-01-07 10:04:18

F#函數式編程

2010-01-26 08:25:06

F#語法F#教程

2012-03-12 12:34:02

JavaF#

2009-05-01 11:17:41

ADNF5思科

2009-09-10 14:18:59

Functional F#

2022-11-10 08:26:54

.NET 7C# 11

2010-03-26 19:22:08

F#代理

2009-11-16 09:05:46

CodeTimer

2010-05-13 09:21:44

F#Visual Stud

2010-04-06 15:20:56

ASP.NET MVC

2010-01-15 08:33:13

F#F#類型推斷F#教程

2009-08-05 16:04:27

C# Actor模型

2010-03-26 19:03:19

F#異步并行模式

2009-08-13 17:39:48

F#數據類型Discriminat

2011-06-09 09:52:41

F#

2009-11-09 17:51:51

F#函數式編程

2010-03-26 18:31:59

F#異步并行模式

2009-08-19 09:42:34

F#并行排序算法
點贊
收藏

51CTO技術棧公眾號

亚洲人视频在线| 永久看片925tv| 色综合久久久网| 色播一区二区| 国产精品美女午夜爽爽| 91精品国产欧美一区二区18 | 国产黄色片免费观看| 色婷婷av一区二区| 久久久亚洲影院你懂的| 少妇饥渴放荡91麻豆| 91福利精品在线观看| 中文字幕视频一区二区三区久| 产国精品偷在线| 一级做a爰片久久毛片| 国产精品99一区二区三区| 亚洲成人精品久久| 伊人成人222| а√在线天堂官网| 国产精品美女久久久久久2018 | 国产sm精品调教视频网站| 欧美又大粗又爽又黄大片视频| 99热在线观看精品| 免费看成人哺乳视频网站| 91精品婷婷国产综合久久性色 | 少妇视频在线观看| 综合亚洲深深色噜噜狠狠网站| 精品一区二区视频| 精品国产无码一区二区三区| 人人狠狠综合久久亚洲| 午夜精品福利电影| 妺妺窝人体色www在线下载| 成人精品亚洲| 亚洲精品永久免费| 国产一级黄色录像| 亚洲国产中文在线二区三区免| 色狠狠一区二区| 三上悠亚久久精品| 午夜成年人在线免费视频| 国产精品私人影院| 欧美一区亚洲二区| 天堂av在线7| 天堂网在线播放| 欧美码中文字幕在线| 亚洲国产精品久久| 苍井空张开腿实干12次| 国产高清精品二区| 欧美另类一区二区三区| 亚洲免费看av| 成人在线高清| 欧亚一区二区三区| 日本熟妇人妻中出| 日本精品另类| 欧洲精品在线观看| 另类小说色综合| 色8久久影院午夜场| 色婷婷一区二区三区四区| 国产黄页在线观看| 久久久男人天堂| 精品国产精品自拍| 九色在线视频观看| 久久影院午夜精品| 日韩欧美国产中文字幕| 中文字幕无码精品亚洲35| 538在线观看| 亚洲成人激情av| 99热久久这里只有精品| 国产资源在线观看入口av| 亚洲电影在线播放| 日韩精品视频一区二区在线观看| 福利在线免费视频| 色哦色哦哦色天天综合| 欧美日韩在线成人| 精品三区视频| 欧美三级视频在线播放| 超碰人人草人人| 免费观看在线一区二区三区| 欧美r级在线观看| 国产精品99久久久精品无码| 成人资源在线播放| 日韩激情片免费| 亚洲一级中文字幕| 日韩欧美不卡| 欧美国产日韩二区| 欧美一级片免费在线观看| 日韩不卡在线观看日韩不卡视频| 国产精品人成电影| 国产aⅴ爽av久久久久成人| 国产91富婆露脸刺激对白| 国产一区二区免费看| 婷婷激情图片久久| 日韩精品免费在线视频| 熟女高潮一区二区三区| 欧美天天综合| 免费91麻豆精品国产自产在线观看| 久久综合成人网| 亚洲欧美激情诱惑| 国产欧美婷婷中文| 亚洲第一大网站| 久久久久久久电影| 国产对白在线播放| 97人人在线视频| 在线中文字幕一区二区| 99热这里只有精品2| 日韩a级大片| www.久久色.com| 韩国av免费观看| 蜜桃一区二区三区在线观看| 懂色一区二区三区av片| 九色在线观看视频| 一区二区三区在线免费观看| 国产无套内射久久久国产| 亚洲影视资源| 亚洲精品一二区| 国产va在线播放| 日日摸夜夜添夜夜添国产精品| 91精品国产99久久久久久红楼 | 天堂av中文在线观看| 欧美三级电影一区| 中文在线永久免费观看| 久久精品影视| 欧美制服第一页| 99国产在线播放| 久久精品视频在线看| 在线观看av的网址| 欧美成人三级| 亚洲欧美www| 国产网址在线观看| 国内国产精品久久| 亚洲国产精品毛片| 周于希免费高清在线观看| 7878成人国产在线观看| 中文字幕在线1| 亚洲免费观看| 99蜜桃在线观看免费视频网站| 91在线高清| 日本高清不卡视频| 久久久精品人妻无码专区| 国色天香一区二区| 91久热免费在线视频| 国产福利小视频在线观看| 欧美日韩国产色视频| 日本精品一二三区| 午夜精品剧场| 91视频免费网站| 免费在线观看黄色网| 欧美午夜在线一二页| 无码人妻精品一区二区中文| 亚洲一区中文| 久久免费99精品久久久久久| av今日在线| 亚洲第一网站免费视频| 久久久久久久久久91| 国产精品99久久不卡二区| 欧美 日韩 国产 在线观看| 岛国精品在线| 中文字幕av一区中文字幕天堂 | 欧美巨大xxxx做受沙滩| 欧美高清www午色夜在线视频| 成人一级片免费看| 免费的国产精品| 午夜啪啪免费视频| 国产aa精品| 欧美另类在线观看| 亚洲男女视频在线观看| 亚洲超碰精品一区二区| 国产成人av无码精品| 在线综合亚洲| 蜜桃免费一区二区三区| 国产在线|日韩| 尤物yw午夜国产精品视频明星| 国产精品熟女视频| 国产精品素人视频| 人妻少妇偷人精品久久久任期| 国产精品久久| 久久久久久久久久久久久久久久av | 国产精品777777| 国产欧美日韩另类视频免费观看 | 国产不卡视频一区二区三区| 97免费视频观看| 牲欧美videos精品| 国产精品第10页| 老司机午夜在线视频| 日韩欧美资源站| 西西44rtwww国产精品| 国产亚洲精久久久久久| 女人高潮一级片| 亚洲天堂激情| 欧美日韩电影一区二区| 精品国产黄a∨片高清在线| 久久人人爽亚洲精品天堂| 成人av免费播放| 欧美日韩国产一区中文午夜| 午夜黄色福利视频| 大桥未久av一区二区三区中文| 成人小视频在线看| 中文一区一区三区免费在线观看| 国产欧美综合精品一区二区| 欧美va在线| 欧美大片va欧美在线播放| 日漫免费在线观看网站| 欧美高清dvd| 欧美国产成人精品一区二区三区| 中文字幕在线不卡一区| 久久午夜夜伦鲁鲁片| 久久国产三级精品| 蜜桃传媒一区二区三区| 欧美大人香蕉在线| 久久久久久久有限公司| 激情小视频网站| 欧美变态挠脚心| 国产有码一区二区| 久草在线资源福利站| 久久久精品999| 国产视频二区在线观看| 日韩欧美123| 艳妇乳肉豪妇荡乳av| 精品欧美aⅴ在线网站| 精品自拍偷拍视频| 国产欧美日韩亚州综合| 熟妇人妻久久中文字幕| 狠狠色丁香婷综合久久| 九九视频精品在线观看| 国产欧美午夜| 蜜臀av性久久久久蜜臀av| 欧美一级精品| 久久波多野结衣| 中文字幕亚洲在线观看| 成人精品视频99在线观看免费 | 91精产国品一二三产区别沈先生| 亚洲综合99| 国产精品一色哟哟| 欧美三级午夜理伦三级中文幕| 亚洲精品一区二区三区四区五区| 丝袜美腿综合| 国产综合第一页| 在这里有精品| 97中文在线| 9999精品| 成人免费午夜电影| 激情中国色综合| 国产精品久久999| 日韩伦理三区| 国产精品6699| 欧美成人ⅴideosxxxxx| 97在线观看视频| sm在线播放| 久久久久久久久国产精品| 在线观看小视频| 另类美女黄大片| 操你啦视频在线| 久久天天躁狠狠躁夜夜躁2014| 91精品大全| 日韩小视频在线| 日本www在线| 久久精品视频中文字幕| www久久日com| 中文字幕天堂网| 一区二区小说| 欧美日韩在线观看一区| 三级精品视频| 久久精品99久久| 综合伊思人在钱三区| 9191成人精品久久| 青草网在线观看| 色综合咪咪久久| 国产吞精囗交久久久| 成人网在线免费视频| 在线观看免费视频国产| 成人免费视频app| 亚洲成av人片在线观看无| aaa国产一区| 一级性生活大片| 国产色综合久久| 黑人と日本人の交わりビデオ| 欧美国产日韩精品免费观看| 在线日韩视频| 成年人深夜视频| 亚洲经典在线看| 黄色一级大片在线观看| 日韩电影在线观看电影| 日本人视频jizz页码69| 国产麻豆午夜三级精品| 国产精九九网站漫画| 91在线视频播放| 欧美另类极品videosbestfree| 欧美草逼视频| 欧美性视频网站| 六九午夜精品视频| 福利视频一区二区三区| 久久综合色占| 黄色免费高清视频| 99国产一区| 亚洲欧美日韩精品一区| 成人国产精品视频| 色撸撸在线视频| 亚洲高清视频的网址| 丰满熟女人妻一区二区三| 日韩欧美国产系列| 精品视频一二区| 欧美精品videossex88| 韩国主播福利视频一区二区三区| 91精品国产综合久久香蕉| 一区二区三区人妻| 销魂美女一区二区三区视频在线| 日日躁夜夜躁aaaabbbb| 成人动漫av在线| 日本午夜精品视频| 丁香五六月婷婷久久激情| 国产尤物视频在线观看| 日韩精品免费在线视频观看| xvideos国产在线视频| 日韩av黄色在线观看| 91精品久久久久久综合五月天 | 中文在线免费观看| 亚洲精品99久久久久| 国产成人高清精品| 国产精品jizz在线观看麻豆| 99久久免费精品国产72精品九九| 视频一区二区在线| 一区二区三区高清视频在线观看| 欧美一级特黄aaa| 久久久电影一区二区三区| 国产一级黄色av| 在线播放日韩导航| 成人动漫在线免费观看| 国产69精品久久久久久| 国产精品极品| 日韩中文在线字幕| 久久精品国产精品亚洲精品 | 国产不卡精品视频| 日韩在线播放一区| 韩日一区二区| 水蜜桃一区二区| 视频一区中文字幕国产| 国产国语性生话播放| 亚洲国产aⅴ天堂久久| 国产精品91在线观看| 日韩毛片一区| 欧美日韩在线精品一区二区三区| 最新亚洲视频| 久久国产劲爆∧v内射| 亚洲精品中文在线影院| 国产精品久久久久久免费| 自拍偷拍亚洲在线| 成人h在线观看| 先锋影音日韩| 免费成人av在线| 中文字幕在线观看二区| 欧美群妇大交群中文字幕| 亚洲精品承认| 国产美女精彩久久| 久久视频在线| 久久久久久久久久一区| 中文字幕一区二区在线播放| 中文字幕在线视频第一页| 日韩一区在线视频| 成人污污www网站免费丝瓜| 影音先锋成人资源网站| 狠狠色狠狠色合久久伊人| 欧美成人精品欧美一级私黄| 欧美成人一区二区三区| 黄网站在线观| 久久久久久高清| 久久永久免费| 欧美黄色高清视频| 在线播放亚洲一区| 欧美日韩色网| 精品国产乱码久久久久久88av | 日韩三级视频| 青青在线视频免费| 国产精品成人免费| 性一交一乱一伧老太| 97视频在线观看免费| 精品在线99| 日韩精品视频一二三| 亚洲精品国久久99热| 蜜桃视频污在线观看| 欧美最近摘花xxxx摘花| 91官网在线| 亚洲午夜久久久影院| 亚洲精品一区av| 日韩成人三级视频| 久久女同精品一区二区| 亚洲一区二区影视| 欧美激情一区二区三区高清视频| 精品国产午夜肉伦伦影院| 777米奇影视第四色| 中文字幕在线不卡一区二区三区| 精品国产99久久久久久宅男i| 97人人模人人爽人人喊中文字| 国产成人调教视频在线观看| 亚洲精品国产久| 日韩欧亚中文在线| 国产黄色小视频在线| 精品一卡二卡三卡四卡日本乱码 | 日本三级韩国三级久久| 国产电影一区二区在线观看| 小毛片在线观看| 51精品秘密在线观看| 成人一区福利|