日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Go語言中 enum 實現方式有哪些?一定要絕對類型安全嗎?

來源: 責編: 時間:2024-02-02 09:22:16 284觀看
導讀嗨!大家好,本文 Go 語言小技巧系列的第十二篇,往期文章查看:Go 語言小技巧。你是否了解過 Go 中的枚舉呢?枚舉,即 enum,可用于表示一組范圍固定的值,它能助我們寫出清晰、安全的代碼。以編寫游戲程序為一個簡單案例:游戲中的角

嗨!大家好,本文 Go 語言小技巧系列的第十二篇,往期文章查看:Go 語言小技巧。ZxY28資訊網——每日最新資訊28at.com

你是否了解過 Go 中的枚舉呢?ZxY28資訊網——每日最新資訊28at.com

枚舉,即 enum,可用于表示一組范圍固定的值,它能助我們寫出清晰、安全的代碼。ZxY28資訊網——每日最新資訊28at.com

以編寫游戲程序為一個簡單案例:游戲中的角色有如戰士、法師或者弓箭手,這種范圍固定的值,就可以用枚舉來表示。ZxY28資訊網——每日最新資訊28at.com

但 Go 中,枚舉的表現方式不像在某些其他語言中那樣直接。我們要想在 Go 中用好枚舉,就要了解 Go 中枚舉的不同表示形式和使用注意點。ZxY28資訊網——每日最新資訊28at.com

使用 iota 和常量

在 Go 中,使用 iota 和常量是最常見的表示枚舉的方式。ZxY28資訊網——每日最新資訊28at.com

什么是 iota?ZxY28資訊網——每日最新資訊28at.com

iota 是 Go 中是一個非常特別的 Keyword,它可以幫助我們按一定規則創建一系列相關的常量,而無需手動為每個變量單獨賦值。這一點與枚舉的用途天然契合。ZxY28資訊網——每日最新資訊28at.com

不了解上面文字的含義?ZxY28資訊網——每日最新資訊28at.com

讓我們來看一個例子,基于 iota 快速創建特定規則的常量。ZxY28資訊網——每日最新資訊28at.com

示例代碼,如下所示:ZxY28資訊網——每日最新資訊28at.com

type Weekday intconst (    Sunday    Weekday = iota // 0    Monday                   // 1    Tuesday                  // 2    Wednesday                // 3    Thursday                 // 4    Friday                   // 5    Saturday                 // 6)

例子中,Weekday 類型有 7 個值,分別代表一周的七天。內部值從 0 開始,iota 自動增加賦值給每個常量,從 Sunday 到 Saturday 分別賦值 0-6。ZxY28資訊網——每日最新資訊28at.com

圖片圖片ZxY28資訊網——每日最新資訊28at.com

現在,我們就不用手動給每個常量賦值。ZxY28資訊網——每日最新資訊28at.com

iota 還有很多騷操作,本文目標不在此,就不展開了。ZxY28資訊網——每日最新資訊28at.com

這種方法的優點是簡單,提供了一定程度上類型安全,但它也有局限性。ZxY28資訊網——每日最新資訊28at.com

我覺得主要是兩點不足。ZxY28資訊網——每日最新資訊28at.com

首先,對比其他語言的枚舉,它不能直接從字符串轉換到枚舉類型,以上面代碼為例,它不能從 "Sunday" 字符串轉為 Sunday 枚舉值。ZxY28資訊網——每日最新資訊28at.com

其次,它的類型安全不是絕對安全。ZxY28資訊網——每日最新資訊28at.com

如上的 Weekday 類型,我們雖不能將一個明確類型的變量賦值給 Weekday 類型變量:ZxY28資訊網——每日最新資訊28at.com

day := 0 // int// compiler: cannot use day (variable of type int) // as Weekday value in variable declaration [IncompatibleAssign]var sunday Weekday = day

但卻可以將一個非 Weekday 類的字面量賦值給它。ZxY28資訊網——每日最新資訊28at.com

// 字面量 10 賦值給類型為 Weekday 的 day 變量var day Weekday = 10

很明顯,10 這個數字并不在 Weekday 的有效范圍,但卻可以有效賦值而并沒有報錯。ZxY28資訊網——每日最新資訊28at.com

圖片圖片ZxY28資訊網——每日最新資訊28at.com

如果是其他枚舉機制完善的 enum 類型的語言,肯定是無法編譯通過的。ZxY28資訊網——每日最新資訊28at.com

除了最基礎的實現方式,我們繼續看看還有哪些其他表示形式吧。ZxY28資訊網——每日最新資訊28at.com

支持字符串轉化的枚舉值

我們在開發 Web 應用時,常會遇到要將枚舉值以字符串形式表示的需求,特別是在與前端對接時。那么,就讓我們先嘗試實現這一個需求,string 變量與枚舉變量相互轉化。ZxY28資訊網——每日最新資訊28at.com

圖片圖片ZxY28資訊網——每日最新資訊28at.com

這個問題說來簡單,Go 語言中,我們可采用字符串常量作為枚舉值。ZxY28資訊網——每日最新資訊28at.com

示例代碼,如下所示:ZxY28資訊網——每日最新資訊28at.com

type HttpMethod stringconst (    Get    HttpMethod = "GET"    Post   HttpMethod = "POST"    Put    HttpMethod = "PUT"    Delete HttpMethod = "DELETE")

這種方法簡單直觀,而且也易于與 JSON 等數據格式轉換。ZxY28資訊網——每日最新資訊28at.com

type Request struct {    Method HttpMethod    URL    string}func main() {    r := Request{Method: Get, URL: "https://zhihu.com"}    result, _ := json.Marshal(r)    fmt.Printf("%s/n", result)}

輸出:ZxY28資訊網——每日最新資訊28at.com

{"Method":"GET","URL":"https://zhihu.com"}

當如果我們還想保留原始的 iota 的整型枚舉值,畢竟它更輕量,占用內存空少。這是否可以實現呢?我們嘗試一下吧。ZxY28資訊網——每日最新資訊28at.com

定義如下:ZxY28資訊網——每日最新資訊28at.com

type HttpMethod intconst (    Get    HttpMethod = iota    Post    Put    Delete)

只要在枚舉類型上增加整型值與字符串兩者間相互轉化的方法即可。ZxY28資訊網——每日最新資訊28at.com

代碼如下所示:ZxY28資訊網——每日最新資訊28at.com

// 從 string 轉為 HttpMethodfunc NewFromString(method string) HttpMethod {  switch h {  case "Get":    // 省略 ...  case "Delete":  default:    return Get // default is Get or error, panic  }}// 從 HttpMethod 轉為 stringfunc (h HttpMethod) String() string {  switch h {  case Get:    return "Get"    // 省略 ...  default:    return "Unknown" // or error, panic  }}

我們實現從 string 構造 enum 方法,和從 enum 類型轉為 string 的 String 方法。ZxY28資訊網——每日最新資訊28at.com

這里存在的一個問題,如果希望支持友好的 JSON 序列化反序列化的話,即枚舉用字符串表示,則需要為 HttpMethod 新增方法,實現 json.Marshaler和json.Unmarshaler接口,自定義這個轉化過程。ZxY28資訊網——每日最新資訊28at.com

圖片圖片ZxY28資訊網——每日最新資訊28at.com

代碼如下:ZxY28資訊網——每日最新資訊28at.com

// MarshalJSON 實現 json.Marshaler 接口func (h HttpMethod) MarshalJSON() ([]byte, error) {    return json.Marshal(h.String())}// UnmarshalJSON 實現 json.Unmarshaler 接口func (h *HttpMethod) UnmarshalJSON(data []byte) error {    var method string    if err := json.Unmarshal(data, &method); err != nil {        return err    }    *h = NewFromString(method)    return nil}

如果去找一些開源項目,可能會發現一些實現了這種 enum 的包,你只要通過 iota 定義枚舉類型,從字符串和枚舉間轉化的代碼可通過命令直接生成。ZxY28資訊網——每日最新資訊28at.com

robpike 開發過一個工具名為 stringer[1],可直接基于類似如上 HttpMethod 定義生成 String() 方法,不過它不是完整的 enum 支持。ZxY28資訊網——每日最新資訊28at.com

//go:generate stringer -type=HttpMethodtype HttpMethod intconst (    Get    HttpMethod = iota    Post    Put    Delete)

我們執行 go generate 即可為 HttpMethod 類型生成 String 方法。ZxY28資訊網——每日最新資訊28at.com

go generate

這里有個提前,要單獨安裝下 stringer 命令。ZxY28資訊網——每日最新資訊28at.com

不過,即使到現在,依然存在類型安全的問題,類似 var Hello HttpMethod = 10 這樣的代碼依然有效。ZxY28資訊網——每日最新資訊28at.com

繼續吧!ZxY28資訊網——每日最新資訊28at.com

結構體枚舉值

GO 中可基于結構體類型,實現枚舉效果。ZxY28資訊網——每日最新資訊28at.com

舉例說明,我們創建一個顏色的枚舉,要求不僅有顏色的名字,還有顏色的 RGB 值。同時,為了方便記錄,我們可以給它加上一個枚舉整型值。ZxY28資訊網——每日最新資訊28at.com

type Color struct {    Index int    Name  string    RGB   string}

這樣我們就有了一個顏色的枚舉,每個顏色都有一個索引、名字和 RGB 值。ZxY28資訊網——每日最新資訊28at.com

如何使用呢?ZxY28資訊網——每日最新資訊28at.com

類似于前面的方式,我們直接定義,如下所示:ZxY28資訊網——每日最新資訊28at.com

var (      Red   = Color{0, "Red", "#FF0000"}      Green = Color{1, "Green", "#00FF00"}      Blue  = Color{2, "Blue", "#0000FF"})

這種方法比較靈活,但也相對復雜。ZxY28資訊網——每日最新資訊28at.com

好處也比較明顯,如現在能存儲的信息也更加豐富,前面類似于整型與字符串的各種轉化都變的輕而易舉了。我們直接整型數值 Color.Index、字符串 Color.Name。ZxY28資訊網——每日最新資訊28at.com

不過,如果要最大化與其他庫結合,如自定義 JSON 轉化規則,要實現 JSON 序列和反序列接口,字符串格式化要實現 Stringer 接口等。ZxY28資訊網——每日最新資訊28at.com

還有,這種結構其實不是常量類型的,就存在數據可更改的問題。不過,有這個安全需求的話,可考慮將成員字段私有化,通過方法變更即可。ZxY28資訊網——每日最新資訊28at.com

結構體類似命名空間效果

在網上看到個有點傻的設計,順便也提一下吧。ZxY28資訊網——每日最新資訊28at.com

假設,我們有很多枚舉類型,擔心可能會出現命名沖突,可以用結構體來創建一個“命名空間”,把相關的枚舉值組織在一起:ZxY28資訊網——每日最新資訊28at.com

示例代碼如下所示:ZxY28資訊網——每日最新資訊28at.com

var Colors = struct {    Red, Green, Blue Color}{      Red   = Color{0, "Red", "#FF0000"}      Green = Color{1, "Green", "#00FF00"}      Blue  = Color{2, "Blue", "#0000FF"}}

上面的例子中定義了 Colors 變量,它是匿名結構體類型,字段名表示顏色,我們可通過 Colors.xxx 形式調用顏色。ZxY28資訊網——每日最新資訊28at.com

我初期看到這個寫法,還以為限定了類型可定義的枚舉值范圍。發現其實不是,我依然可使用 Color 類型定義新值。ZxY28資訊網——每日最新資訊28at.com

這很不優雅,也很雞肋,其實我完全可以新建 package 實現。不過既然發現了這個方案,就寫到這里吧。ZxY28資訊網——每日最新資訊28at.com

類型安全?

到這里,其實所有實現方式都沒有解決一個問題,那就是定義完枚舉后,依然繼續添加新的枚舉值。ZxY28資訊網——每日最新資訊28at.com

我真的想實現這樣的能力呢?該如何做呢?ZxY28資訊網——每日最新資訊28at.com

以前面 HttpMethod 為例,我要做的就是禁止通過 HttpMethod(1) 創建新枚舉值。ZxY28資訊網——每日最新資訊28at.com

這不是很簡單嗎?ZxY28資訊網——每日最新資訊28at.com

圖片圖片ZxY28資訊網——每日最新資訊28at.com

我們只要將枚舉實現封裝成一個 package,將類型小寫,如 httpMethod,暴露它的類似 FromString 和其它函數,實現強制通過轉化函數它。ZxY28資訊網——每日最新資訊28at.com

package httpmethodtype httpmethod stringconst (  Get  = "Get"  Post = "Post")func FromString(method string) httpmethod {  switch method {  case "Get":    return Get  case "Post":    return Post  }}

現在,枚舉創建必須通過方法,我們就可以在其中實現限定創建規則。ZxY28資訊網——每日最新資訊28at.com

方法可能挺好,但好像沒見到這么玩的?ZxY28資訊網——每日最新資訊28at.com

為什么呢?ZxY28資訊網——每日最新資訊28at.com

我的猜想是,開發時我們不會隨意創建新的枚舉值,對于邊界數據的傳遞,確保通過轉化函數處理不就行了嗎?ZxY28資訊網——每日最新資訊28at.com

真實場景

對真實場景下枚舉的使用,有價值之處主要在與其他系統的對接。ZxY28資訊網——每日最新資訊28at.com

圖片圖片ZxY28資訊網——每日最新資訊28at.com

舉例而言,如來自前端 API 或數據庫,有時可能出現一些異常值。對這類場景,通過前面介紹,可提供轉化函數,在其中設置檢查規則。如果發現異常選擇丟棄,執行如 error 或 panic。ZxY28資訊網——每日最新資訊28at.com

而對于內部系統,如果使用類似于 protobuffer 協議,可在協議上限定好枚舉范圍,標記異常數據等。ZxY28資訊網——每日最新資訊28at.com

當然,可能出現因為發布時間次序或者兄弟團隊忘記通知等,導致系統間枚舉值對不齊的情況,也會按上面的邏輯丟棄、error 等,便于即使發現。ZxY28資訊網——每日最新資訊28at.com

對于團隊合作這類場景,最好的解決方式,還是要在設計系統時,考慮上下游的兼容性,而不是每當有變動,全員亂糟糟,這最容易導致生產事故了。ZxY28資訊網——每日最新資訊28at.com

其實無論哪一種情況,重點在于保證進入系統的數據是否可通過轉化檢測,而不是多此一舉,限制類似于 HttpMethod("Get") 的類型轉化,因為沒有人會這么寫代碼。ZxY28資訊網——每日最新資訊28at.com

總結

Go 語言中,枚舉的表達方式多種多樣。從簡單的 iota 到復雜的結構體方式,每種方法都有其適用場景。作為開發者,最好是根據自己的具體需求,選擇合適的實現方式。ZxY28資訊網——每日最新資訊28at.com

最后,希望這篇文章能幫助你在使用 Go 語言時,更加靈活且游刃有余地使用枚舉 enum。ZxY28資訊網——每日最新資訊28at.com

博客地址:Go語言中 enum 實現方式有哪些?一定要類型安全嗎?[2]ZxY28資訊網——每日最新資訊28at.com

引用鏈接

[1] stringer: https://pkg.go.dev/golang.org/x/tools/cmd/stringerZxY28資訊網——每日最新資訊28at.com

[2] Go語言中 enum 實現方式有哪些?一定要類型安全嗎?: https://www.poloxue.com/posts/2024-02-02-how-to-use-enums-type-in-golang/ZxY28資訊網——每日最新資訊28at.com

ZxY28資訊網——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-71453-0.htmlGo語言中 enum 實現方式有哪些?一定要絕對類型安全嗎?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: SpringBoot生產級WebSocket集群實踐,支持10萬連接!

下一篇: JSX/TSX 是 Vue 前端開發的未來嗎?

標簽:
  • 熱門焦點
  • 鴻蒙OS 4.0公測機型公布:甚至連nova6都支持

    華為全新的HarmonyOS 4.0操作系統將于今天下午正式登場,官方在發布會之前也已經正式給出了可升級的機型產品,這意味著這些機型會率先支持升級享用。這次的HarmonyOS 4.0支持
  • 7月安卓手機性能榜:紅魔8S Pro再奪榜首

    7月份的手機市場風平浪靜,除了紅魔和努比亞帶來了兩款搭載驍龍8Gen2領先版處理器的新機之外,別的也想不到有什么新品了,這也正常,通常6月7月都是手機廠商修整的時間,進入8月份之
  • 三言兩語說透設計模式的藝術-簡單工廠模式

    一、寫在前面工廠模式是最常見的一種創建型設計模式,通常說的工廠模式指的是工廠方法模式,是使用頻率最高的工廠模式。簡單工廠模式又稱為靜態工廠方法模式,不屬于GoF 23種設計
  • 破圈是B站頭上的緊箍咒

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之每年的暑期檔都少不了瞄準追劇女孩們的古偶劇集,2021年有優酷的《山河令》,2022年有愛奇藝的《蒼蘭訣》,今年卻輪到小破站抓住了追
  • 年輕人的“職場羞恥感”,無處不在

    作者:馮曉亭 陶 淘 李 欣 張 琳 馬舒葉來源:燃次元“人在職場,應該選擇什么樣的著裝?”近日,在網絡上,一個與著裝相關的帖子引發關注,在該帖子里,一位在高級寫字樓亞洲金
  • OPPO、vivo、小米等國內廠商Q2在印度智能手機市場份額依舊高達55%

    7月20日消息,據外媒報道,研究機構的報告顯示,在全球智能手機出貨量同比仍在下滑的大背景下,印度這一有潛力的市場也未能幸免,出貨量同比也有下滑,多家廠
  • 三星顯示已開始為AR設備研發硅基LED微顯示屏

    7月18日消息,據外媒報道,隨著蘋果首款頭顯產品Vision Pro在6月份正式推出,AR/VR/MR等頭顯產品也就將成為各大公司下一個重要的競爭領域,對顯示屏這一關
  • 英特爾Xe HPG游戲顯卡:擁有512EU,單風扇版本

    據10 月 30 日外媒 TheVerge 消息報道,英特爾 Xe HPG Arc Alchemist 的正面實被曝光,不僅擁有 512 EU 版顯卡,還擁有 128EU 的單風扇版本。另外,這款顯卡 PCB
  • “買真退假” 這種“羊毛”不能薅

    □ 法治日報 記者 王春   □ 本報通訊員 胡佳麗  2020年初,還在上大學的小東加入了一個大學生兼職QQ群。群主“七王”在群里介紹一些刷單賺
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
伊人久久大香线蕉av超碰演员| 欧美激情va永久在线播放| 国产欧美视频在线观看| 国产视频一区二区在线观看| 国产日韩欧美在线看| 亚洲国产日韩一区| 国产精品日韩二区| 久久影院亚洲| 欧美精品在线一区二区三区| 在线日韩中文| 久久一区二区三区超碰国产精品| 欧美日韩国产二区| 国产精品va| 免费91麻豆精品国产自产在线观看| 亚洲中无吗在线| 久久精品免费观看| 欧美日本韩国一区| 国产日韩精品在线播放| 亚洲观看高清完整版在线观看| 一区二区三区精密机械公司 | 黄色成人在线网址| 日韩视频免费观看高清在线视频 | 亚洲欧美精品在线| 免费不卡视频| 国产精品毛片在线看| 亚洲大片一区二区三区| 亚洲在线视频一区| 欧美成年网站| 国产欧美精品在线播放| 亚洲精品综合久久中文字幕| 欧美专区在线观看| 欧美三日本三级少妇三99| 一色屋精品视频在线观看网站| 一区二区三区色| 女主播福利一区| 国产欧美午夜| 在线视频亚洲欧美| 欧美成人午夜影院| 狠狠色狠狠色综合人人| 亚洲专区一区| 欧美日韩免费一区| 亚洲二区在线| 欧美专区第一页| 欧美视频在线观看免费| 亚洲国产精品悠悠久久琪琪| 久久精品国产99国产精品| 欧美性事免费在线观看| 日韩午夜三级在线| 欧美成人激情在线| 极品尤物av久久免费看| 欧美一区二区三区免费在线看| 欧美午夜激情在线| 亚洲毛片在线免费观看| 蜜桃久久av| 国产一区二区欧美日韩| 午夜国产精品影院在线观看| 欧美日韩午夜视频在线观看| 亚洲欧洲在线播放| 老**午夜毛片一区二区三区| 国内精品伊人久久久久av一坑| 午夜精品久久久久久久99樱桃| 欧美丝袜第一区| 99re视频这里只有精品| 欧美激情在线免费观看| 亚洲国产精品一区二区尤物区 | 亚洲欧美日韩另类| 欧美日韩中文在线观看| 亚洲每日在线| 欧美激情综合| 99精品免费视频| 欧美男人的天堂| 亚洲伦理一区| 欧美日韩国产精品成人| 亚洲精品久久嫩草网站秘色| 免费在线欧美视频| 亚洲国产视频a| 欧美黄色影院| 99re热这里只有精品免费视频| 欧美日韩123| 一本一本久久a久久精品综合妖精| 欧美另类高清视频在线| 99av国产精品欲麻豆| 欧美日韩午夜| 亚洲一区二区三区精品动漫| 国产精品美女久久| 欧美一激情一区二区三区| 国产视频一区在线观看| 久久久91精品国产一区二区精品| 黄色精品网站| 女人香蕉久久**毛片精品| 亚洲青涩在线| 欧美日韩在线播放三区四区| 亚洲制服欧美中文字幕中文字幕| 国产精品在线看| 久久成人av少妇免费| 影音先锋国产精品| 欧美国产日产韩国视频| 夜夜嗨av一区二区三区| 国产精品久久久久免费a∨大胸| 亚洲欧美中文日韩在线| 国产在线精品二区| 美日韩精品免费| 日韩一级欧洲| 国产精品三区www17con| 久久精品99无色码中文字幕| 在线国产欧美| 欧美日韩ab片| 亚洲欧美日韩一区二区在线| 精久久久久久久久久久| 欧美精品久久99| 在线中文字幕不卡| 国产视频一区免费看| 欧美成人精品一区二区| 99精品欧美一区二区三区综合在线| 国产精品扒开腿爽爽爽视频| 久久精品日韩一区二区三区| 亚洲国产精品成人一区二区| 欧美日韩伊人| 欧美专区日韩视频| 亚洲精品国产精品乱码不99 | 亚洲精品五月天| 国产精品久久久久久久app| 欧美中文字幕精品| 亚洲精品国产拍免费91在线| 国产精品免费视频观看| 久久在线免费观看| 亚洲视频第一页| 极品尤物av久久免费看| 国产精品99一区二区| 久久精品亚洲| 日韩一级黄色大片| 国产一区香蕉久久| 欧美日本在线播放| 久久经典综合| av不卡免费看| 狠狠爱综合网| 国产精品成人国产乱一区| 久久露脸国产精品| 亚洲视频专区在线| 在线播放视频一区| 国产精品高潮久久| 久久夜色精品国产| 亚洲男人影院| 91久久在线观看| 国产日韩精品综合网站| 欧美日韩国产成人在线免费| 久久成人免费日本黄色| 一区二区三区日韩欧美| 亚洲国产精品一区在线观看不卡 | 国产亚洲精品福利| 欧美日韩一区免费| 蜜桃av久久久亚洲精品| 午夜视频在线观看一区二区三区 | 欧美伊人久久久久久午夜久久久久| 亚洲毛片一区二区| 一区二区三区在线观看欧美| 国产精品免费区二区三区观看| 欧美激情在线狂野欧美精品| 久久精品亚洲国产奇米99| 一区二区三区不卡视频在线观看| 亚洲第一在线视频| 国产婷婷一区二区| 欧美特黄一级大片| 欧美护士18xxxxhd| 久久综合久久久| 欧美在线播放视频| 亚洲一区二三| 9国产精品视频| 亚洲欧洲精品一区二区| 极品少妇一区二区三区精品视频| 国产伦精品一区二区三区照片91| 欧美日韩一区二区在线视频| 欧美大片一区| 蜜桃久久av| 久久亚洲一区二区| 久久久免费精品视频| 小处雏高清一区二区三区| 亚洲一区二区三区免费观看| 99re6这里只有精品| 亚洲人成在线播放| 亚洲国产91精品在线观看| 国内揄拍国内精品少妇国语| 国产美女精品在线| 国产精品日韩专区| 国产精品美女久久| 国产精品v一区二区三区| 欧美日韩精品在线视频| 欧美精品亚洲二区| 欧美国产一区视频在线观看| 欧美 亚欧 日韩视频在线| 麻豆国产va免费精品高清在线| 久久久综合网站| 久久免费国产| 美国十次了思思久久精品导航| 另类成人小视频在线| 久久久综合香蕉尹人综合网| 久久精品综合网| 久久久久久国产精品一区| 久久九九久精品国产免费直播| 欧美在线日韩在线| 久久精品国产91精品亚洲| 久久九九精品| 麻豆成人小视频| 欧美精品一区二区蜜臀亚洲 |