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

從源碼的角度看Go語言Flag庫如何解析命令行參數(shù)!

開發(fā) 后端
Parse的代碼里用到了一個,CommandLine共享變量,這就是內(nèi)部庫維護的FlagSet,所有的參數(shù)都會插到里面的變量地址向地址的指向賦值綁定。

 [[416691]]

我上周五喝酒喝到晚上3點多,確實有點罩不住啊,整個周末都在休息和睡覺,文章鴿了幾天,想不到就有兩個人跑了。

不得不感嘆一下,自媒體的太殘酷了,時效就那么幾天,斷更就沒人愛。你們說好了愛我的,愛呢?哼

昨晚就在寫這篇文章了,沒想到晚上又遇到發(fā)版本,確實不容易,且看且珍惜。

  • 標準庫 flag
  • flag的簡寫方式
  • 從源碼來看flag如何解析參數(shù)
  • 從源碼想到的拓展用法
  • 小結(jié)
  • 引用

標準庫 flag

命令行程序應(yīng)該能打印出幫助信息,傳遞其他命令行參數(shù),比如-h就是flag庫的默認幫助參數(shù)。

  1. ./goapi -h 
  2. Usage of ./goapi: 
  3.   -debug 
  4.         is debug 
  5.   -ip string 
  6.         Input bind address (default "127.0.0.1"
  7.   -port int 
  8.         Input bind port (default 80) 
  9.   -version 
  10.         show version information 

goapi是我build出來的一個二進制go程序,上面所示的四個參數(shù),是我自定義的。

按提示的方法,可以像這樣使用參數(shù)。

  1. ./goapi -debug -ip 192.168.1.1 
  2. ./goapi -port 8080 
  3. ./goapi -version 

像上面-version這樣的參數(shù)是bool類型的,只要指定了就會設(shè)置為true,不指定時為默認值,假如默認值是true,想指定為false要像下面這樣顯式的指定(因為源碼里是這樣寫的)。

  1. ./goapi -version=false 

下面這幾種格式都是兼容的

  1. -isbool    #同于 -isbool=true 
  2. -age=x     #-和等號 
  3. -age x     #-和空格 
  4. --age=x    #2個-和等號 
  5. --age x    #2個-和空格 

flag庫綁定參數(shù)的過程很簡單,格式為

  1. flag.(name string, value bool, usage string) *類型 

如下是詳細的綁定方式:

  1. var ( 
  2.     showVersion = flag.Bool("version"false"show version information"
  3.     isDebug = flag.Bool("debug"false"is debug"
  4.     ip      = flag.String("ip""127.0.0.1""Input bind address"
  5.     port    = flag.Int("port", 80, "Input bind port"

可以定義任意類型的變量,比如可以表示是否debug模式、讓它來輸出版本信息、傳入需要綁定的ip和端口等功能。

綁定完參數(shù)還沒完,還得調(diào)用解析函數(shù)flag.Parse(),注意一定要在使用參數(shù)前調(diào)用哦,使用過程像下面這樣:

  1. func main() { 
  2.  flag.Parse() 
  3.  if *showVersion { 
  4.   fmt.Println(version) 
  5.   os.Exit(0) 
  6.  } 
  7.  if *isDebug { 
  8.   fmt.Println("set log level: debug"
  9.  } 
  10.  fmt.Println(fmt.Sprintf("bind address: %s:%d successfully",*ip,*port)) 

全部放在main函數(shù)里,不太雅觀,建議把這些單獨放到一個包里,或者放在main函數(shù)的init()里,看起來不僅舒服,也便于閱讀。

flag的簡寫方式

有時候可能我們要給某個全局配置變量賦值,flag提供了一種簡寫的方式,不用額外定義中間變量。像下面這樣

  1. var ( 
  2.  ip          string 
  3.  port        int 
  4.  
  5. func init() { 
  6.  flag.StringVar(&ip, "ip""127.0.0.1""Input bind address(default: 127.0.0.1)"
  7.  flag.IntVar(&port, "port", 80, "Input bind port(default: 80)"
  8. func main() { 
  9.  flag.Parse() 
  10.  fmt.Println(fmt.Sprintf("bind address: %s:%d successfully", ip, port)) 

這樣寫可以省掉很多判斷的代碼,也避免了使用指針,命令行的使用方法還是一樣的。

從源碼來看flag如何解析參數(shù)

其實我們把之前的綁定方式打開來看,在源碼里就是調(diào)用了xxVar函數(shù),以Bool類型為例。

  1. func (f *FlagSet) Bool(name string, value bool, usage string) *bool { 
  2.  p := new(bool) 
  3.  f.BoolVar(p, name, value, usage) 
  4.  return p 

上面的代碼用到了BoolVal函數(shù),它的功能是把需要綁定的變量設(shè)置為默認值,并調(diào)用f.Var進一步處理,這里p是一個指針,所以只要改變指向的內(nèi)容,就可以影響到外部綁定所用的變量:

  1. func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) { 
  2.  f.Var(newBoolValue(value, p), name, usage) 
  3.  
  4. type boolValue bool 
  5.  
  6. func newBoolValue(val bool, p *bool) *boolValue { 
  7.  *p = val 
  8.  return (*boolValue)(p) 
  • newBoolValue 函數(shù)可以得到一個boolValue類型,它是bool類型重命名的。在此包中所有可作為參數(shù)的類型都有這樣的定義。
  • 在flag包的設(shè)計中有兩個重要的類型,F(xiàn)lag和FlagSet分別表示某個特定的參數(shù),和一個無重復的參數(shù)集合。

f.Var函數(shù)的作用就是把參數(shù)封裝成Flag,并合并到FlagSet中,下面的代碼就是核心過程:

  1. func (f *FlagSet) Var(value Value, name string, usage string) { 
  2.  // Remember the default value as a string; it won't change. 
  3.  flag := &Flag{name, usage, value, value.String()} 
  4.  _, alreadythere := f.formal[name
  5.  if alreadythere { 
  6.   //...錯誤處理省略 
  7.  } 
  8.  if f.formal == nil { 
  9.   f.formal = make(map[string]*Flag) 
  10.  } 
  11.  f.formal[name] = flag 

FlagSet結(jié)構(gòu)體中起作用的是formal map[string]*Flag類型,所以說,flag把程序中需要綁定的變量包裝成一個字典,后面解析的時候再一一賦值。

我們已經(jīng)知道了,在調(diào)用Parse的時候,會對參數(shù)解析并為變量賦值,使用時就可以得到真實值。展開看看它的代碼

  1. func Parse() { 
  2.  // Ignore errors; CommandLine is set for ExitOnError. 
  3.  // 調(diào)用了FlagSet.Parse 
  4.  CommandLine.Parse(os.Args[1:]) 
  5. // 返回一個FlagSet 
  6. var CommandLine = NewFlagSet(os.Args[0], ExitOnError) 

Parse的代碼里用到了一個,CommandLine共享變量,這就是內(nèi)部庫維護的FlagSet,所有的參數(shù)都會插到里面的變量地址向地址的指向賦值綁定。

上面提到FlagSet綁定的Parse函數(shù),看看它的內(nèi)容:

  1. func (f *FlagSet) Parse(arguments []string) error { 
  2.  f.parsed = true 
  3.  f.args = arguments 
  4.  for { 
  5.   seen, err := f.parseOne() 
  6.   if seen { continue } 
  7.   if err == nil {...} 
  8.   switch f.errorHandling { 
  9.   case ContinueOnError: return err 
  10.   case ExitOnError: 
  11.    if err == ErrHelp { os.Exit(0) } 
  12.    os.Exit(2) 
  13.   case PanicOnError: panic(err) 
  14.   } 
  15.  } 
  16.  return nil 
  • 上面的函數(shù)內(nèi)容太長了,我收縮了一下。
  • 可看到解析的過程實際上是多次調(diào)用了parseOne(),它的作用是逐個遍歷命令行參數(shù),綁定到Flag,就像翻頁一樣。
  • 用switch對應(yīng)處理錯誤,決定退出碼或直接panic。

parseOne就是解析命令行輸入綁定變量的過程了:

  1. func (f *FlagSet) parseOne() (bool, error) { 
  2.  //... 
  3.  s := f.args[0] 
  4.  //... 
  5.  if s[1] == '-' { ...} 
  6.  name := s[numMinuses:] 
  7.  if len(name) == 0 || name[0] == '-' || name[0] == '=' { 
  8.   return false, f.failf("bad flag syntax: %s", s) 
  9.  } 
  10.  
  11.  f.args = f.args[1:] 
  12.  //... 
  13.  m := f.formal 
  14.  flag, alreadythere := m[name] // BUG 
  15.  // ...如果不存在,或者需要輸出幫助信息,則返回 
  16.  // ...設(shè)置真實值調(diào)用到 flag.Value.Set(value) 
  17.  if f.actual == nil { 
  18.   f.actual = make(map[string]*Flag) 
  19.  } 
  20.  f.actual[name] = flag 
  21.  return true, nil 
  • parseOne 內(nèi)部會解析一個輸入?yún)?shù),判斷輸入?yún)?shù)格式,獲取參數(shù)值。
  • 解析過程就是逐個取出程序參數(shù),判斷-、=取參數(shù)與參數(shù)值
  • 解析后查找之前提到的formal map中有沒有存在此參數(shù),并設(shè)置真實值。
  • 把設(shè)置完畢真實值的參數(shù)放到f.actual map中,以供它用。
  • 一些錯誤處理和細節(jié)的代碼我省略掉了,感興趣可以自行看源碼。
  • 實際上就是逐個參數(shù)解析并設(shè)置到對應(yīng)的指針變量的指向上,讓返回值出現(xiàn)變化。

flag.Value.Set(value) 這里是設(shè)置數(shù)據(jù)真實值的代碼,Value長這樣

  1. type Value interface { 
  2.     String() string 
  3.     Set(string) error 

它被設(shè)計成一個接口,不同的數(shù)據(jù)類型自己實現(xiàn)這個接口,返回給用戶的地址就是這個接口的實例數(shù)據(jù),解析過程中,可以通過 Set 方法修改它的值,這個設(shè)計確實還挺巧妙的。

  1. func (b *boolValue) String() string { 
  2.   return strconv.FormatBool(bool(*b))  
  3. func (b *boolValue) Set(s string) error { 
  4.     v, err := strconv.ParseBool(s) 
  5.     if err != nil { 
  6.         err = errParse   
  7.     } 
  8.     *b = boolValue(v) 
  9.     return err 

從源碼想到的拓展用法

flag的常用方法也學會了,基本原理也了解了,我怎么那么厲害。哈哈哈。

有沒有注意到整個過程都圍繞了FlagSet這個結(jié)構(gòu)體,它是最核心的解析類。

在庫內(nèi)部提供了一個 *FlagSet 的實例對象 CommandLine,它通過NewFlagSet方法創(chuàng)建。并且對它的所有方法封裝了一下直接對外。

官方的意思很明確了,說明我們可以用到它做些更高級的事情。先看看官方怎么用的。

  1. var CommandLine = NewFlagSet(os.Args[0], ExitOnError) 

可以看到調(diào)用的時候是傳入命令行第一個參數(shù),第二個參數(shù)表示報錯時應(yīng)該呈現(xiàn)怎樣的錯誤。

那就意味著我們可以根據(jù)命令行第一個參數(shù)不同而呈現(xiàn)不同的表現(xiàn)!

我定義了兩個參數(shù)foo或者bar,代表兩個不同的指令集合,每個指令集匹配不同的命令參數(shù),效果如下:

  1. $ ./subcommands  
  2. expected 'foo' or 'bar' subcommands 
  3.  
  4. $ ./subcommands foo -h 
  5. Usage of foo: 
  6.   -enable 
  7.         enable 
  8.          
  9. $./subcommands foo -enable 
  10. subcommand 'foo' 
  11.   enable: true 
  12.   tail: [] 

這是怎么實現(xiàn)的呢?其實就是用NewFlagSet方法創(chuàng)建多個FlagSet再分別綁定變量,如下:

  1. fooCmd := flag.NewFlagSet("foo", flag.ExitOnError) 
  2. fooEnable := fooCmd.Bool("enable"false"enable"
  3.  
  4. barCmd := flag.NewFlagSet("bar", flag.ExitOnError) 
  5. barLevel := barCmd.Int("level", 0, "level"
  6.  
  7. if len(os.Args) < 2 { 
  8.     fmt.Println("expected 'foo' or 'bar' subcommands"
  9.     os.Exit(1) 
  • 定義兩個不同的FlagSet,接受foo或bar參數(shù)。
  • 綁定錯誤時退出。
  • 分別為每個FlagSet綁定要解析的變量。
  • 如果判斷命令行輸入?yún)?shù)少于2個時退出(因為第0個參數(shù)是程序名本身)。

然后根據(jù)第一個參數(shù),判斷應(yīng)該匹配到哪個指令集:

  1. switch os.Args[1] { 
  2. case "foo"
  3.     fooCmd.Parse(os.Args[2:]) 
  4.     fmt.Println("subcommand 'foo'"
  5.     fmt.Println("  enable:", *fooEnable) 
  6.     fmt.Println("  tail:", fooCmd.Args()) 
  7. case "bar"
  8.     barCmd.Parse(os.Args[2:]) 
  9.     fmt.Println("subcommand 'bar'"
  10.     fmt.Println("  level:", *barLevel) 
  11.     fmt.Println("  tail:", barCmd.Args()) 
  12. default
  13.     fmt.Println("expected 'foo' or 'bar' subcommands"
  14.     os.Exit(1) 
  • 使用switch來切換命令行參數(shù),綁定不同的變量。
  • 對應(yīng)不同變量輸出不同表現(xiàn)。
  • x.Args()可以打印未匹配到的其他參數(shù)。

補充:使用NewFlagSet時,flag 提供三種錯誤處理的方式:

  • ContinueOnError: 通過 Parse 的返回值返回錯誤
  • ExitOnError: 調(diào)用 os.Exit(2) 直接退出程序,這是默認的處理方式
  • PanicOnError: 調(diào)用 panic 拋出錯誤

小結(jié)

通過本節(jié)我們了解到了標準庫flag的使用方法,參數(shù)變量綁定的兩種方式,還通過源碼解析了內(nèi)部實現(xiàn)是如何的巧妙。

我們還使用源碼暴露出來的函數(shù),接收不同參數(shù)匹配不同指令集,這種方式可以讓應(yīng)用呈現(xiàn)完成不同的功能;

我想到的是用來通過環(huán)境變量改變命令用法、或者讓程序復用大段邏輯呈現(xiàn)不同作用時使用。

但現(xiàn)在微服務(wù)那么流行,大多功能集成在一個服務(wù)里是不科學的,如果有重復代碼應(yīng)該提煉成共同模塊才是王道。

你還想到能哪些使用場景呢?

引用

源碼包 https://golang.org/src/flag/flag.go

命令行子命令 https://gobyexample-cn.github.io/command-line-subcommands

命令行解析庫 flag https://segmentfault.com/a/1190000021143456

騰訊云文檔flag https://cloud.tencent.com/developer/section/1141707#stage-100022105

往期精彩回顧

本文轉(zhuǎn)載自微信公眾號「機智的程序員小熊」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系機智的程序員小熊公眾號。

 

責任編輯:武曉燕 來源: 機智的程序員小熊
相關(guān)推薦

2021-01-13 05:29:26

命令行

2023-07-05 08:38:48

GolangGo語言

2024-05-15 17:05:16

GoLangflagcast

2023-10-30 01:00:42

Go語言Cobra庫

2021-11-15 14:30:49

Pythonargparse編程語言

2014-06-16 09:28:08

Linux命令行

2018-09-10 09:30:25

Linux命令應(yīng)用

2021-11-08 10:45:07

Python命令工具

2021-01-06 09:47:51

內(nèi)存Go語言

2010-11-24 15:33:59

mysql命令行參數(shù)

2010-03-10 17:23:37

Python 命令行參

2009-07-20 09:55:30

華為命令行解析華為認證

2010-08-20 10:05:23

用戶命令

2010-07-15 10:47:22

Perl命令行

2010-07-20 14:02:38

Perl命令行參數(shù)

2010-07-26 09:32:41

Perl命令行

2020-12-11 06:44:16

命令行工具開發(fā)

2020-12-10 16:16:08

工具代碼開發(fā)

2011-08-22 11:51:13

Linuxconfigure

2010-07-15 11:08:23

Perl命令行
點贊
收藏

51CTO技術(shù)棧公眾號

蜜桃传媒视频第一区入口在线看| 中文字幕不卡在线视频极品| 国产一级大片免费看| 国产精品毛片久久久久久久av| 俺要去色综合狠狠| 欧美三区免费完整视频在线观看| 四虎影视永久免费在线观看一区二区三区| 蜜臀尤物一区二区三区直播| 日韩综合网站| 日韩欧美高清一区| 国产精品12345| 四虎影视2018在线播放alocalhost| 国产亚洲在线观看| 在线电影av不卡网址| 日本男人操女人| 在线看免费av| 懂色av一区二区三区免费看| 韩剧1988免费观看全集| 微拍福利一区二区| 久草综合在线| 亚洲欧美福利一区二区| 国产专区一区二区三区| 中文天堂在线播放| 欧美激情视频一区二区三区在线播放 | 国产成人亚洲综合无码| 亚洲av成人精品毛片| 日本不卡视频在线观看| 久久99精品久久久久久噜噜 | 成人黄色av电影| 日韩av免费在线播放| 人妻无码一区二区三区| 日韩av黄色| 午夜精品久久久久久久久久久| 日韩和欧美的一区二区| 国产高清不卡视频| 美女诱惑一区| 色综合久久天天综线观看| 国产吞精囗交久久久| 国产精品一区二区精品视频观看| 精品福利在线视频| 免费观看中文字幕| 成年在线电影| 91网站最新网址| 国产在线精品成人一区二区三区| 日韩三级视频在线| 天天综合一区| 亚洲人成电影网站色www| 久久无码人妻一区二区三区| japanese23hdxxxx日韩| 亚洲成人免费av| 一区二区三区四区免费视频| 欧美一区二区三区少妇| 粉嫩aⅴ一区二区三区四区| 国产精品久久久久久久久久 | 国产视频手机在线| 日韩av成人高清| 91av视频在线播放| 欧美极品aaaaabbbbb| 99久久99久久精品国产片桃花| 日韩精品在线观看一区二区| 中文字幕在线综合| 欧美成人ⅴideosxxxxx| 亚洲va天堂va国产va久| 日韩人妻精品一区二区三区| 97电影在线看视频| 久久久久国产精品麻豆ai换脸| 国产一区二区无遮挡| 国产一区二区在线不卡| 久久精品国产99久久6| 国产999精品| 亚洲久久在线观看| 亚洲国产国产亚洲一二三| 欧美成人免费一级人片100| 国产成人免费观看网站| 精品国产一区二区三区四区| 亚洲精品天天看| 懂色av粉嫩av蜜乳av| 日韩精选在线| 亚洲精品视频网上网址在线观看| 中文字幕a在线观看| 国产精品调教视频| 亚洲精品国产精品国产自| 佐佐木明希电影| 一区二区在线免费播放| 精品日韩一区二区三区 | 免费观看在线色综合| 欧美高清激情视频| 国产精品suv一区二区| 在线成人www免费观看视频| 久久久久免费精品国产| 免费在线观看黄网站| 欧美日韩国产综合网| 欧美黑人xxxx| 国产精品500部| 免费日韩视频| 国产精品毛片a∨一区二区三区|国| 波多野结衣理论片| 精油按摩中文字幕久久| 91av一区二区三区| 秋霞欧美在线观看| 2023国产精品| 一区二区免费在线观看| 成人免费视屏| 亚欧色一区w666天堂| 日韩在线一级片| 国产精品原创视频| 3d成人h动漫网站入口| 亚洲成人福利视频| 精品国产影院| 这里只有视频精品| 曰本女人与公拘交酡| 亚洲国产黄色| 国产精品日韩av| 亚洲在线精品视频| 成人午夜电影网站| 欧美日韩另类丝袜其他| 香蕉视频国产在线观看| 亚洲国产一二三| 熟妇人妻无乱码中文字幕真矢织江 | 国产亚洲一区字幕| 亚洲一区 在线播放| 少妇av在线| 色偷偷88欧美精品久久久| 一个色综合久久| 欧美日韩一区二区三区四区不卡| 中文字幕日韩精品有码视频| 国产一级久久久| 久久天天综合| 99久久伊人精品影院| 国产日本在线观看| 亚洲成人一二三| 不卡的在线视频| 色狠狠久久av综合| 亚洲欧美另类人妖| 欧美日韩精品在线观看视频| 日精品一区二区| 成人三级在线| 成年在线电影| 精品国产乱码久久久久久虫虫漫画| 久草精品在线播放| theporn国产在线精品| 中文字幕日韩欧美在线| 久久久久久久黄色片| 日韩视频一区| 亚洲专区国产精品| 91在线网址| 欧美午夜影院在线视频| 激情av中文字幕| 天天躁日日躁狠狠躁欧美| 中文字幕日韩精品在线| 中文字幕一区二区人妻视频| 成人成人成人在线视频| 日韩视频一二三| 日韩久久一区| 亚洲一区第一页| 亚洲精品www久久久久久| 成人在线视频一区二区| 欧美h视频在线观看| 成人四虎影院| 夜夜嗨av色综合久久久综合网| 日韩精品一卡二卡| 另类综合日韩欧美亚洲| 91精品国产电影| 国产ts在线观看| 伊人www22综合色| 538在线一区二区精品国产| 日韩一级视频在线观看| 国产综合婷婷| 91在线播放国产| 国产三级在线播放| 91精品国产一区二区三区香蕉 | 91免费公开视频| 日本亚洲天堂网| 美日韩免费视频| 老司机2019福利精品视频导航| 精品亚洲夜色av98在线观看 | 免费观看不卡av| 热久久视久久精品18亚洲精品| 香港一级纯黄大片| 欧美视频裸体精品| 中文字幕制服丝袜| 亚洲国内欧美| 免费看成人午夜电影| 青草在线视频| 亚洲第五色综合网| 91精品国产乱码久久久张津瑜| 成人免费视频国产在线观看| 国产一区二区网| 国产精品久久久久久久久久白浆| 久久久久久91| 神马精品久久| 欧美综合久久久| av黄色免费网站| 麻豆精品一区二区av白丝在线| 中文字幕中文字幕一区三区| 免费一级欧美在线大片| 国产69精品久久久久9| 色一情一乱一区二区三区| 欧美性猛交xxxx乱大交极品| 永久免费av无码网站性色av| 韩日av一区二区| 2018中文字幕第一页| 亚洲2区在线| 欧美成人久久久| 亚洲人妻一区二区| 欧美日韩国产一区二区三区地区| 久久久久久久久久97| 成人sese在线| 天天干天天干天天干天天干天天干| 91综合网人人| 韩国成人一区| 成人软件在线观看| 欧美猛交免费看| 欧美视频免费一区二区三区| 欧美三级在线视频| 免费成人深夜天涯网站| 国产99久久久国产精品潘金| 日本在线视频www| 欧美一区网站| 久热国产精品视频一区二区三区 | 97视频在线看| 91caoporn在线| 精品粉嫩超白一线天av| 奴色虐av一区二区三区| 一区二区三区四区在线| 久久无码人妻精品一区二区三区| 久久精品国产99久久6| a级黄色一级片| 中文不卡在线| 国产伦精品一区二区三区四区视频| 蜜桃精品在线| 欧美极品美女视频网站在线观看免费| 国产九色在线| 7777精品伊人久久久大香线蕉超级流畅 | 中文字幕一区二区三三 | 日日鲁鲁鲁夜夜爽爽狠狠视频97| 精品中文字幕一区二区三区av| 91视频婷婷| 日韩在线激情| 国产精品va在线| av资源网在线播放| 欧美成人午夜激情视频| av片在线免费观看| 亚洲精品中文字幕av| av 一区二区三区| 色婷婷综合久久久久中文一区二区 | 日本一区二区精品视频| 欧美freesex8一10精品| 91久久久一线二线三线品牌| 欧美精品总汇| 欧洲成人性视频| 美女高潮视频在线看| 欧美国产在线电影| 1区2区在线观看| 久久精品精品电影网| 91社区在线| 亚洲人a成www在线影院| 人妻无码中文字幕| 欧美草草影院在线视频| 国产成人精品一区二区无码呦| 午夜一级黄色片| 国产精品乱码人人做人人爱 | 日韩精品乱码免费| 亚洲中文字幕无码专区| 亚洲三级影院| 国产人妻人伦精品| 国产精品v亚洲精品v日韩精品 | 亚洲男人天堂九九视频| 日本aaa在线观看| 国产视频亚洲精品| 欧美日韩在线精品一区二区三区激情综| 亚洲精品电影网| 性感美女一级片| 亚洲第一精品久久忘忧草社区| 黄色福利在线观看| 亚洲精品久久视频| 无码国产伦一区二区三区视频| 日韩国产高清污视频在线观看| 日本护士...精品国| 亚洲色图综合久久| www.亚洲资源| 久久天天躁狠狠躁夜夜爽蜜月| av免费网站在线观看| 午夜免费久久久久| 自拍偷拍欧美视频| 国产精品视频在线观看| 国产成人免费视频网站视频社区| 成人国产精品色哟哟| 给我免费播放日韩视频| 久久综合伊人77777麻豆| 欧美精品一区二区三区中文字幕 | 日韩三级久久| 国产一区二区三区免费不卡| 奇米色欧美一区二区三区| 亚洲精品第一区二区三区| 欧美欧美天天天天操| 久色视频在线播放| 免费在线观看精品| 精品国产乱码久久久久久1区二区| 久久99久国产精品黄毛片色诱| 在线播放av网址| 国产日产精品一区| 极品颜值美女露脸啪啪| 欧美日韩精品在线播放| 欧美人一级淫片a免费播放| 日韩一区二区在线观看| 亚州男人的天堂| 日韩中文字幕av| 国产亚av手机在线观看| 国产精品小说在线| 高潮按摩久久久久久av免费| 日韩亚洲不卡在线| 国内在线观看一区二区三区| 亚洲老女人av| 不卡一区在线观看| 99热这里只有精品4| 五月激情丁香一区二区三区| 国产污视频网站| 亚洲电影免费观看高清完整版在线观看 | 日韩av在线看免费观看| 亚洲欧美一区二区在线观看| 成人精品在线看| 欧美人伦禁忌dvd放荡欲情| 神马久久久久久久久久| 日韩中文字幕精品| 欧美爱爱视频| 精选一区二区三区四区五区| 911久久香蕉国产线看观看| 大肉大捧一进一出好爽视频| 狠狠色综合色综合网络| 国产又爽又黄无码无遮挡在线观看| 综合在线观看色| 国产99免费视频| 亚洲国产福利在线| 日本aa在线| 国产精品一区二区久久久 | 蜜桃视频日韩| 久久久久久久久久久9不雅视频| 黄色一级免费大片| 91视频免费看| 久久国产一级片| 91精品综合久久久久久| 午夜伦全在线观看| 国产精品aaa| 要久久爱电视剧全集完整观看| 国内少妇毛片视频| 精品综合久久久久久8888| 国产传媒国产传媒| 色哟哟日韩精品| 视频在线不卡| 午夜精品久久久久久久99热浪潮| 一区二区三区欧洲区| 精品一区二区三区毛片| 老司机免费视频一区二区| 亚洲第一成人网站 | 中文字幕一区二区三区四区视频 | 久久精品亚洲国产| 亚洲二区av| 一级特黄录像免费播放全99| 免费观看一级特黄欧美大片| 丁香花五月婷婷| 欧美日韩国产123区| 日韩伦理在线电影| 国产精品一香蕉国产线看观看| 欧美美女一区| 日韩av片专区| 综合在线观看色| 国产av一区二区三区| 久99九色视频在线观看| 大香伊人久久精品一区二区| www.av毛片| 99久久99精品久久久久久| 日韩欧美性视频| 国产亚洲人成网站在线观看| 激情中国色综合| 国产a级片免费看| 国产精品99久久久久久宅男| 日韩欧美一区二区一幕| 亚洲精品日韩久久久| 91国拍精品国产粉嫩亚洲一区| 四虎一区二区| 成人综合婷婷国产精品久久免费| 欧美亚洲天堂网| 精品呦交小u女在线| 都市激情亚洲综合| 制服丝袜综合日韩欧美| 国产大陆a不卡| 韩国av免费观看| 亚洲欧美国产精品va在线观看| 日韩电影精品| 欧美 亚洲 视频| 99精品视频在线观看| 久久久久久少妇| 精品国产一区二区三区在线观看 | 国产人妻777人伦精品hd| gogogo免费视频观看亚洲一| 波多野结衣啪啪| 久久色在线播放| 蜜臀av一区| www.超碰97.com|