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

Go工具鏈版本已不由你定:Go和Toolchain指令詳解

開發 前端
本文深入探討了Go語言在版本管理和工具鏈兼容性方面的重要變革,特別是Go 1.21及以后的版本如何強化向前兼容性。

Go語言自誕生以來,就一直將向后兼容性作為其核心理念之一。Go1兼容性承諾[1]確保了為Go1.0編寫的代碼能夠在后續的Go1.x版本中持續正確地編譯和運行。這一承諾為Go的成功奠定了堅實的基礎,它不僅保障了穩定性,也大大減輕了隨著語言演進帶來的代碼維護負擔。然而,兼容性的內涵并不僅限于向后兼容。向前兼容性,即舊版本的工具鏈能夠優雅地處理針對新版本編寫的代碼,對于打造流暢的開發體驗同樣至關重要。

在Go 1.21版本[2]之前,向前兼容性在某種程度上是一個被忽視的領域。盡管go.mod文件中的go指令可以標明模塊預期的Go版本,但在實際中,它更像是一個指導性建議,而非強制性規則。舊版本的Go工具鏈會嘗試編譯那些需要較新版本的代碼,這經常導致令人困惑的錯誤,更有甚者會出現“靜默成功”的情況——代碼雖然可以編譯,但由于較新版本中的細微改動,其運行時行為可能并不正確。

Go 1.21的發布標志著這一現狀的重大轉變。該版本引入了健壯且自動化的工具鏈管理機制,將go指令轉變為一項強制性要求,并簡化了使用不同Go版本進行開發的工作流程。即將發布的Go 1.24版本在此基礎上進一步增強,引入了tool指令[3],允許開發者指定對外部工具及其特定版本的依賴,從而進一步提升了代碼的可重復性和項目的可維護性。

這些改進進一步明確和鞏固了go命令作為全方位依賴管理器的角色定位,它不僅管理外部模塊,還負責管理Go工具鏈版本,以及越來越多的外部開發工具(如下圖):

圖片圖片

不過向前兼容性規則的明確以及toolchain指令的引入也給Go開發者帶來一定的理解上的復雜性,并且在使用Go 1.21版本之后,我們可能遇到會遇到一些因Go工具鏈版本選擇而導致的編譯問題。

本文將通過一系列典型場景和詳細的示例,幫助讀者全面理解Go向前兼容性的規則,以及go指令以及toolchain指令對Go工具鏈選擇的細節,從而讓大家能更加自信地駕馭Go開發中不斷演進的技術環境。

接下來,我們就從對向前兼容性的理解開始!

1. 理解向前兼容性

向前兼容性,在編程語言的語境中,指的是舊版本的編譯器或運行時環境能夠處理針對該語言的新版本編寫的代碼。它與向后兼容性相對,后者確保的是新版本的語言能夠處理為舊版本編寫的代碼。向后兼容性對于維護現有代碼庫至關重要,而向前兼容性則是在使用不斷演進的語言和依賴項時獲得流暢開發體驗的關鍵所在。

向前兼容性的挑戰源于新語言版本通常會引入新的特性、語法變更或對標準庫的修改。如果舊的工具鏈遇到了依賴于這些新元素的代碼,它可能無法正確地編譯或解釋這些代碼。理想情況下,工具鏈應該能夠識別出代碼需要一個更新的版本,并提供清晰的錯誤提示,從而阻止編譯或執行。

在Go 1.21之前的版本中,向前兼容性并沒有得到嚴格的保證。讓我們來看一個例子。我們用Go 1.18泛型語法編寫一個泛型函數Print:

// toolchain-directive/demo1/mymodule.go
package mymodule

func Print[T any](s T) {
    println(s)
}

// toolchain-directive/demo1/go.mod
module mymodule

go 1.18

如果你嘗試使用Go 1.17版本來構建這個模塊,你將會遇到類似以下的錯誤:

$go version
go version go1.17 darwin/amd64

$go build            
# mymodule
./mymodule.go:3:6: missing function body
./mymodule.go:3:11: syntax error: unexpected [, expecting (
note: module requires Go 1.18

這些錯誤信息具有一定的誤導性,它們指向的是語法錯誤,而不是問題的本質:這段代碼使用了Go 1.18版本中才引入的泛型特性[4]。雖然go命令確實打印了一條有用的提示(note: module requires Go 1.18),但對于規模大一些的項目來說,在滿屏的編譯錯誤中,這條提示很容易被忽略。

而比上面這個示例更隱蔽的問題是所謂的“靜默成功”。

設想這樣一個場景:Go標準庫中的某個bug在Go 1.19版本中被修復了。你編寫了一段代碼,并在不知情的情況下依賴于這個bug修復。如果你沒有使用任何Go 1.19版本特有的語言特性,并且你的go.mod文件中指定的是go 1.19,那么舊版本的Go 1.18工具鏈將會毫無怨言地編譯你的代碼并獲得成功。然而,在運行這段代碼時,你的程序可能會表現出不正確的行為,因為那個bug在Go 1.18的標準庫中依然存在。這就是“靜默成功”——編譯過程沒有任何錯誤提示,但最終生成的程序卻是有缺陷的。

在Go 1.21版本之前,go.mod文件中的go指令更多的是一種指導性意見。它表明了期望使用的Go版本,但舊的工具鏈并不會嚴格執行它。這種執行上的疏漏是導致Go開發者面臨向前兼容性挑戰的主要原因。

Go 1.21版本從根本上改變了go指令的處理方式。它不再是一個可有可無的建議,而是一個強制性的規則。下面我們就來看看Go 1.21及更高版本中是如何確保向前兼容性的。由于多數情況下,我們不會顯式在go.mod顯式指定toolchain指令,因此,我們先來看看沒有顯式指定toolchain指令時,go指令對向前兼容性的影響。

2. 作為規則的go指令:確保向前兼容性(Go 1.21及更高版本)

Go 1.21對Go version、language version、release version等做了更明確的定義,我們先來看一下,這對后續理解go.mod文件中go指令的作用很有幫助。下圖形象的展示了各個version之間的關系:

圖片圖片

Go版本(Go Version),也是發布版本(Release Version)使用1.N.P的版本號形式,其中1.N稱為語言版本(language version),表示實現該版本Go語言和標準庫的Go版本的整體系列。1.N.P是1.N語言版本的一個實現,初始實現是1.N.0,也是1.N的第一次發布!后續的1.N.P成為1.N的補丁發布。

任何兩個Go版本(Go version)都可以進行比較,以判斷一個是小于、大于還是等于另一個。

如果語言版本不同,則語言版本的比較結果決定Go版本的大小。比如:1.21.9 vs. 1.22,前者的語言版本是1.21,后者語言版本是1.22,因此1.21.9 < 1.22。

如果語言版本相同,從小到大的排序為:語言版本本身、按R排序的候選版本(1.NrcR),然后按P排序的發布版本,例如:

1.21 < 1.21rc1 < 1.21rc2 < 1.21.0 < 1.21.1 < 1.21.2。

在Go 1.21之前,Go初始發布版本為1.N,而不是1.N.0,因此對于N < 21,排序被調整為將1.N放在候選版本(rc)之后,例如:

1.20rc1 < 1.20rc2 < 1.20rc3 < 1.20 < 1.20.1。

更早期版本的Go有beta發布,例如1.18beta2。Beta發布在版本排序中被放置在候選版本之前,例如:

1.18beta1 < 1.18beta2 < 1.18rc1 < 1.18 < 1.18.1。

有了上述對Go version等的理解,我們再來看看go.mod中go指令在向前兼容性規則中的作用。

Go 1.21及更高版本中,go.mod文件中的go指令聲明了使用模塊或工作空間(workspace)所需的最低Go版本。出于兼容性原因,如果go.mod文件中省略了go指令行(通常我們都不這么做),則該模塊被視為隱式使用go 1.16這個指令行;如果go.work文件中省略了go指令行,則該工作空間被視為隱式使用go 1.18這個指令行。

那么,Go 1.21及更高版本的Go工具鏈在遇到go.mod中go指令行中的Go版本高于自身時會怎么做呢?下面我們通過四個場景的示例來看一下。

圖片圖片

  • 場景一

當前本地工具鏈go 1.22.0,go.mod中go指令行為go 1.23.0:

// toolchain-directive/demo2/scene1/go.mod
module scene1

go 1.23.0

執行構建:

$go build
go: downloading go1.23.0 (darwin/amd64)
... ...

Go自動下載當前go module中go指令行中的Go工具鏈版本并對當前module進行構建。

  • 場景二

當前本地工具鏈go 1.22.0,go.mod中go指令行為go 1.22.0,但當前module依賴的github.com/bigwhite/a的go.mod中go指令行為go 1.23.1:

// toolchain-directive/demo2/scene2/go.mod
module scene2

go 1.22.0

require (
 github.com/bigwhite/a v1.0.0
) 

replace github.com/bigwhite/a => ../a

執行構建:

$go build
go: module ../a requires go >= 1.23.1 (running go 1.22.0)

Go發現當前go module依賴的go module中go指令行中的Go版本比當前module的更新,則會輸出錯誤提示!

  • 場景三

當前本地工具鏈go 1.22.0,go.mod中go指令行為go 1.22.0,但當前module依賴的github.com/bigwhite/a的go.mod中go指令行為go 1.23.1,而依賴的github.com/bigwhite/b的go.mod中go指令行為go 1.23.2:

// toolchain-directive/demo2/scene3/go.mod
module scene3

go 1.22.0

require (
 github.com/bigwhite/a v1.0.0
 github.com/bigwhite/b v1.0.0
) 

replace github.com/bigwhite/a => ../a
replace github.com/bigwhite/b => ../b

執行構建:

$go build
go: module ../b requires go >= 1.23.2 (running go 1.22.0)

Go發現當前go module依賴的go module中go指令行中的Go版本比當前module的更新,則會輸出錯誤提示!并且選擇了滿足依賴構建的最小的Go工具鏈版本。

  • 場景四

當前本地工具鏈go 1.22.0,go.mod中go指令行為go 1.23.0,但當前module依賴的github.com/bigwhite/a的go.mod中go指令行為go 1.23.1,而依賴的github.com/bigwhite/b的go.mod中go指令行為go 1.23.2:

// toolchain-directive/demo2/scene4/go.mod
module scene4

go 1.23.0

require (
 github.com/bigwhite/a v1.0.0
 github.com/bigwhite/b v1.0.0
) 

replace github.com/bigwhite/a => ../a
replace github.com/bigwhite/b => ../b

執行構建:

$go build
go: downloading go1.23.0 (darwin/amd64)
... ..

Go發現當前go module依賴的go module中go指令行中的Go版本與當前module的兼容,但比本地Go工具鏈版本更新,則會下載當前go module中go指令行中的Go版本進行構建。

從以上場景的執行情況來看,只有選擇了當前go module的工具鏈版本時,才會繼續構建下去,如果本地找不到這個版本的工具鏈,go會自動下載該版本工具鏈再進行編譯(前提是GOTOOLCHAIN=auto)。如果像場景2和場景3那樣,依賴的module的最低Go version大于當前module的go version,那么Go會提示錯誤并結束編譯!后續你需要顯式指定要使用的工具鏈才能繼續編譯!以場景3為例,通過GOTOOLCHAIN顯式指定工具鏈,我們可以看到下面結果:

// demo2/scene3

$GOTOOLCHAIN=go1.22.2 go build
go: downloading go1.22.2 (darwin/amd64)
^C

$GOTOOLCHAIN=go1.23.3 go build
go: downloading go1.23.3 (darwin/amd64)
.. ...

我們看到,go完全相信我們顯式指定的工具鏈版本,即使是不滿足依賴module的最低go版本要求的!

想必大家已經感受到支持新向前兼容規則帶來的復雜性了!這里我們還沒有顯式使用到toolchain指令行呢!但其實,在上述場景中,雖然我們沒有在go.mod中顯式使用toolchain指令行,但Go模塊會使用隱式的toolchain指令行,其隱式的默認值為toolchain goV,其中V來自go指令行中的Go版本,比如go1.22.0等。

接下來我們就簡單地看看toolchain指令行,我們的宗旨是盡量讓事情變簡單,而不是變復雜!

3. toolchain指令行與GOTOOLCHAIN

Go mod的參考手冊[5]告訴我們:toolchain指令僅在模塊為主模塊且默認工具鏈的版本低于建議的工具鏈版本時才有效,并建議:Go toolchain指令行中的go工具鏈版本不能低于在go指令行中聲明的所需Go版本。

也就是說如果對toolchain沒有特殊需求,我們還是盡量隱式的使用toolchain,即保持toolchain與go指令行中的go版本一致。

另外一個影響go工具鏈版本選擇的是GOTOOLCHAIN環境變量,它的值決定了go命令的行為,特別是當go.mod文件中指定的Go版本(通過go或toolchain指令)與當前運行的go命令的版本不同時,GOTOOLCHAIN的作用就體現出來了。

GOTOOLCHAIN可以設置為以下幾種形式:

  • local: 這是最簡單的形式,它指示go命令始終使用其自帶的捆綁工具鏈,不允許自動下載或切換到其他工具鏈版本。即使go.mod文件要求更高的版本,也不會切換。如果版本不滿足,則會報錯。
  • <name> (例如go1.21.3): 這種形式指示go命令使用特定名稱的Go工具鏈。如果系統中存在該名稱的可執行文件(例如在PATH環境變量中找到了go1.21.3),則會執行該工具鏈。否則,go命令會嘗試下載并使用名為<name>的工具鏈。如果下載失敗或找不到,則會報錯。
  • auto(或local+auto): 這是默認設置。在這種模式下,go命令的行為最為智能。它首先檢查當前使用的工具鏈版本是否滿足go.mod文件中go和toolchain指令的要求。如果不滿足,它會根據如下規則嘗試切換工具鏈。
- 如果go.mod中有toolchain行且指定的工具鏈名稱比當前默認的工具鏈更新,則切換到toolchain行指定的工具鏈。
- 如果go.mod中沒有有效的toolchain行(例如toolchain default或沒有toolchain行),但go指令行指定的版本比當前默認的工具鏈更新,則切換到與go指令行版本相對應的工具鏈(例如go 1.23.1對應go1.23.1工具鏈)。
- 在切換時,go命令會優先在本地路徑(PATH環境變量)中尋找工具鏈的可執行文件,如果找不到,則會下載并使用。
  • <name>+auto: 這種形式與auto類似,但它指定了一個默認的工具鏈<name>。go命令首先嘗試使用<name>工具鏈。如果該工具鏈不滿足go.mod文件中的要求,它會按照與auto模式相同的規則嘗試切換到更新的工具鏈。這種方式可以用來設定一個高于內置版本的最低版本要求,同時又允許根據需要自動升級。
  • <name>+path (或local+path): 這種形式與<name>+auto類似,也指定了一個默認的工具鏈<name>。不同之處在于,它禁用了自動下載功能。go命令首先嘗試使用<name>工具鏈,如果不滿足要求,它會在本地路徑中搜索符合要求的工具鏈,但不會嘗試下載。如果找不到合適的工具鏈,則會報錯。

大多數情況我們會使用GOTOOLCHAIN的默認值,即在auto模式下。但是如果在國內自動下載go版本不便的情況下,可以使用local模式,這樣在本地工具鏈版本不滿足的情況下,可以盡快得到錯誤。或是通過<name>強制指定使用特定版本的工具鏈,這樣可以實現對組織內采用的工具鏈版本的精準控制,避免因工具鏈版本不一致而導致的問題。

4. 使用go get管理Go指令行和toolchain指令行

自go module誕生以來,我們始終可以使用go get對go module的依賴進行管理,包括添加/刪除依賴,升降依賴版本等。

就像本文開頭的那個圖中所示,go命令作為全方位依賴管理器的角色定位,它不僅管理外部模塊,還負責管理Go工具鏈版本,以及越來越多的外部開發工具。因此我們也可以使用go get管理指令行和toolchain指令行。

例如,go get go@1.22.1 toolchain@1.24rc1將改變主模塊的go.mod文件,將go指令行改為go 1.22.1,將toolchain指令行改為toolchain go1.24rc1。我們要保證toolchain指令行中的版本始終等于或高于go指令行中的版本。

當toolchain指令行與go指令行完全匹配時,可以省略和隱含,所以go get go@1.N.P時可能會刪除toolchain行。

反過來也是這樣,當go get toolchain@1.N.P時,如果1.N.P < go指令行的版本,go指令行也會隨之被降級為1.N.P,這樣就和toolchain版本一致了,toolchain指令行可能會被刪除。

我們也可以通過下面go get命令顯式刪除toolchain指令行:

$go get toolchain@none

通過go get管理Go指令行和toolchain指令行還會對require中依賴的go module版本產生影響,反之使用go get管理require中依賴的go module版本時,也會對Go指令行和toolchain指令行的版本產生影響!不過這一切都是通過go get自動完成的!下面我們通過示例來具體說明一下。

我們首先通過示例看看go get管理go指令行對require中依賴的Go模塊版本的影響。

當你使用go get升級或降級go.mod文件中的go指令行時,go get 會根據新的Go版本要求,自動調整require指令行中依賴模塊的版本,以滿足新的兼容性要求。比如下面這個升級go版本導致依賴模塊升級的示例。

假設你的模塊mymodule的go.mod文件內容如下:

module example.com/mymodule

go 1.21.0

require (
    example.com/moduleA v1.1.0 // 兼容Go 1.21.0
    example.com/moduleB v1.2.0 // 兼容Go 1.21.0
)

example.com/moduleA和example.com/moduleB的v1.1.0和v1.2.0版本都只兼容到Go 1.21.0。

現在,你執行以下命令升級Go版本:

$go get go@1.23.1

go get會將go.mod文件中的go指令行更新為go 1.23.1。同時,它會檢查require指令行中的依賴模塊,發現example.com/moduleA和example.com/moduleB的v1.1.0和v1.2.0版本可能不兼容Go1.23.1。

假設example.com/moduleA和example.com/moduleB都有更新的版本v1.3.0,且兼容Go 1.23.1,那么go get會自動將require指令行更新為:

module example.com/mymodule

go 1.23.1

require (
    example.com/moduleA v1.3.0 // 兼容Go 1.23.1
    example.com/moduleB v1.3.0 // 兼容Go 1.23.1
)

如果找不到兼容Go 1.23.1 的版本,go get可能會報錯,提示無法找到兼容新Go版本的依賴模塊。

同理,降低go版本也可能觸發require中依賴模塊降級。我們來看下面示例:

假設你的模塊mymodule的go.mod文件內容如下:

module example.com/mymodule

go 1.23.1

require (
 example.com/moduleA v1.3.0 // 兼容 Go 1.22.0及以上
 example.com/moduleB v1.3.0 // 兼容 Go 1.22.0及以上
)

現在,你執行以下命令降低go版本:

$go get go@1.22.0

執行以上命令后,go.mod文件內容變為:

module example.com/mymodule

go 1.22.0

require (
 example.com/moduleA v1.1.0 // 兼容Go 1.21.0及以上
 example.com/moduleB v1.2.0 // 兼容Go 1.21.0及以上
)

在這個例子中, go get go@1.22.0命令會將go指令行降級為go 1.22.0, 同時, go get會自動檢查所有依賴項, 并嘗試將它們降級到與go 1.22.0兼容的最高版本。在這個例子中, example.com/moduleA和example.com/moduleB都被降級到了與go 1.22.0兼容的最高版本。

反過來,使用go get管理require中依賴的Go模塊版本時,也會對go指令行產生影響,我們看一個添加依賴導致go指令行版本升級的示例。

假設你的模塊mymodule的go.mod文件內容如下:

module example.com/mymodule

go 1.21.0

require (
    example.com/moduleA v1.1.0 // 兼容 Go 1.21.0
)

現在,你需要添加一個新的依賴項example.com/moduleC,而example.com/moduleC的最新版本v1.2.0的go.mod文件中指定了go 1.22.0:

// example.com/moduleC 的 go.mod
module example.com/moduleC

go 1.22.0

require (
    ...
)

你執行以下命令添加依賴:

$go get example.com/moduleC@v1.2.0

go get會發現example.com/moduleC的版本v1.2.0需要 Go 1.22.0,而你的模塊當前只兼容Go 1.21.0。因此,go get會自動將你的模塊的go.mod文件更新為:

module example.com/mymodule

go 1.22.0

require (
    example.com/moduleA v1.1.0 // 兼容Go 1.21.0
    example.com/moduleC v1.2.0 // 需要Go 1.22.0
)

go指令行被升級到了go 1.22.0,以滿足新添加的依賴項的要求。

不過無論如何雙向影響,我們只要記住一個原則就夠了,那就是go get和go mod tidy命令使go指令行中的Go版本始終保持大于或等于任何所需依賴模塊的go指令行中的Go版本。

5. 小結

本文深入探討了Go語言在版本管理和工具鏈兼容性方面的重要變革,特別是Go 1.21及以后的版本如何強化向前兼容性。在文章里,我強調了向后兼容性和向前兼容性在開發體驗中的重要性,以及如何通過go指令和新引入的toolchain指令來管理工具鏈版本。

通過文中的示例,我展示了如何在不同場景下處理Go模塊的兼容性問題,并解釋了GOTOOLCHAIN環境變量如何影響工具鏈選擇。最后,我還舉例說明了如何通過使用go get命令有效管理Go指令和依賴模塊的版本,確保代碼的可維護性和穩定性。

不過我們也看到了,為了實現精確的向前兼容,Go引入了不少復雜的規則,短時間內記住這些規則還是有門檻的,我們只能在實踐中慢慢吸收和理解。

本文涉及的源碼可以在這里[6]下載。

參考資料

  • Go Toolchains[7] - https://go.dev/doc/toolchain
  • Forward Compatibility and Toolchain Management in Go 1.21[8] - https://go.dev/blog/toolchain

參考資料

[1] Go1兼容性承諾: https://go.dev/doc/go1compat

[2] Go 1.21版本: https://tonybai.com/2023/08/20/some-changes-in-go-1-21

[3] 引入了tool指令: https://tonybai.com/2024/12/17/go-1-24-foresight-part2/

[4] Go 1.18版本中才引入的泛型特性: https://tonybai.com/2022/04/20/some-changes-in-go-1-18

[5] Go mod的參考手冊: https://go.dev/ref/mod#go-mod-file-toolchain

[6] 這里: https://github.com/bigwhite/experiments/tree/master/toolchain-directive

[7] Go Toolchains: https://go.dev/doc/toolchain

[8] Forward Compatibility and Toolchain Management in Go 1.21: https://go.dev/blog/toolchain

責任編輯:武曉燕 來源: TonyBai
相關推薦

2024-04-12 08:58:45

Go數據工具鏈

2023-01-30 08:46:20

GoGo1兼容性

2014-09-01 14:56:13

投影便攜

2023-04-17 14:32:20

2025-03-28 01:00:00

Go語言版本

2021-11-10 15:37:49

Go源碼指令

2024-06-13 09:10:22

2021-04-09 20:04:34

區塊鏈Go加密

2023-03-13 00:10:46

Go語言版本

2024-01-03 10:00:11

Prometheus指標Go

2023-10-14 12:05:59

KubuntuLinux

2024-02-26 00:02:00

開發Go

2015-08-14 09:21:09

gdb工具調試 Go

2023-09-27 08:26:48

Go標準庫函數

2022-08-15 08:02:09

Go程序函數

2022-04-06 10:12:51

Go供應鏈攻擊風險

2022-04-13 14:49:59

安全供應鏈Go

2023-07-14 08:12:21

計時器unsafecontext

2023-04-02 23:13:07

Go語言bufio
點贊
收藏

51CTO技術棧公眾號

天堂久久一区二区三区| 加勒比久久综合| 亚洲线精品一区二区三区八戒| 99国产在线| 精品91久久久| 日韩精品免费| 日韩久久精品一区| 国产精品宾馆在线精品酒店| 成黄免费在线| 日本亚洲免费观看| 欧美成人午夜激情在线| 天天躁日日躁狠狠躁av| 欧美xxx网站| 中文字幕在线不卡一区二区三区| 91精品久久久久久蜜桃| 亚洲精品1区2区3区| 清纯唯美综合亚洲| 精品久久人人做人人爱| 日韩中文字幕组| www视频在线免费观看| www.成人在线| 国产精品一区二区三区成人| 国产亚洲第一页| 欧美熟乱15p| 精品国产一区久久| 免费看国产黄色片| 九色porny自拍视频在线观看| 中文字幕不卡一区| 国产精品免费看一区二区三区| 欧美国产成人精品一区二区三区| 99久久婷婷| 日韩电影在线观看中文字幕| 在线播放黄色av| 日本欧美日韩| 午夜欧美视频在线观看| 在线播放豆国产99亚洲| 台湾av在线二三区观看| 国产一区欧美二区| 国产精品美女无圣光视频| 日本免费在线播放| 在线观看日韩| 少妇高潮 亚洲精品| 午夜男人的天堂| 国产精品麻豆| 91久久精品一区二区三区| 日本一区午夜艳熟免费| 国产调教视频在线观看| 国产欧美一区在线| 久久久久网址| 欧美特黄一级视频| 国内久久精品视频| 国产精品日韩在线播放| 中文字幕一区二区人妻电影| 亚洲日韩视频| 九九热精品视频国产| 2014亚洲天堂| 日韩伦理视频| 一区国产精品视频| 国产成人精品无码免费看夜聊软件| 亚洲一区二区电影| 日韩欧美国产精品一区| 五月天六月丁香| 欧洲美女精品免费观看视频 | 成人在线高清免费| 亚洲欧美一区二区久久| 亚洲AV无码成人精品一区| yw在线观看| 亚洲国产成人一区二区三区| 日本一区二区三区在线视频| 国产永久免费高清在线观看视频| 26uuu久久天堂性欧美| 久久精品一二三区| 日本韩国一区| 国产婷婷色一区二区三区 | 色琪琪久久se色| 中文字幕一区二区精品| 成人在线观看免费高清| 日韩欧美电影| 久久精品91久久香蕉加勒比| 手机av在线看| 综合激情网站| 久久久久久久色| 欧美一级特黄视频| 日韩电影免费在线看| 国产精品直播网红| 国产精品久久免费| 高清成人免费视频| 精品视频第一区| 国产在线观看免费| 国产精品午夜在线观看| 久久免费视频2| 激情网站在线| 色综合婷婷久久| 国产精品久久久毛片| 91精品国产一区二区在线观看| 日韩精品一区二区三区视频在线观看| 精品国产免费久久久久久婷婷| 久久精品色综合| 亚洲性生活视频| 东方av正在进入| 在线精品观看| 国产精品久久久久久av福利| 国产女人高潮时对白| kk眼镜猥琐国模调教系列一区二区| 蜜桃视频日韩| 麻豆视频在线免费观看| 午夜精品久久久久久不卡8050| 熟妇人妻无乱码中文字幕真矢织江| 日日夜夜一区| 亚洲精品福利视频| 肉色超薄丝袜脚交69xx图片| 欧美视频网站| 国产精品青青在线观看爽香蕉| 国产高潮在线观看| 国产视频一区不卡| av日韩在线看| 99久久综合国产精品二区| 欧美xxxx老人做受| 日本美女bbw| 伊人久久大香线蕉综合热线| 国产精品免费小视频| 后入内射欧美99二区视频 | 男人在线观看视频| 老司机一区二区三区| 亚洲一区制服诱惑| 国产日韩精品在线看| 亚洲成a人v欧美综合天堂| www.com黄色片| 亚洲传媒在线| 欧美日韩成人网| 中国老头性行为xxxx| 99国产精品一区| 激情六月天婷婷| 99亚洲伊人久久精品影院| 亚洲国产中文字幕久久网| √天堂中文官网8在线| 久久婷婷影院| 精品在线观看一区二区| www国产在线观看| 欧美亚洲愉拍一区二区| 国产网站无遮挡| 欧美日韩国产成人精品| 91精品久久久久久久久久另类| 免费黄网站在线观看| 天天色 色综合| 第一页在线视频| 亚洲电影影音先锋| 国产精品一区二区三| 国产在线播放av| 欧美色播在线播放| 国产ts丝袜人妖系列视频| 欧美精品三级| **亚洲第一综合导航网站| www在线播放| 色八戒一区二区三区| 爱爱的免费视频| 亚洲尤物精选| 麻豆av一区二区| 爱草tv视频在线观看992| 日韩女优av电影| 国产在线视频第一页| 风间由美性色一区二区三区 | 99精品免费| 国产欧美综合精品一区二区| 麻豆福利在线观看| 亚洲电影成人av99爱色| 日韩三级一区二区三区| 99久久久无码国产精品| 日本午夜激情视频| 一区二区美女| 日韩av免费在线观看| 国产午夜在线观看| 欧美亚洲愉拍一区二区| 蜜桃av.com| 国产精品一区二区在线观看不卡 | 欧美天天视频| 狠狠色综合欧美激情| 在线观看涩涩| 亚洲网址你懂得| 在线观看免费观看在线| 亚洲视频在线一区观看| 一区二区三区人妻| 国产一区二区三区成人欧美日韩在线观看| 国产一区不卡在线观看| 亚洲插插视频| 在线国产精品播放| 国产精品视频第一页| 一区二区三区四区在线免费观看| 国产精品麻豆入口| 玖玖在线精品| 超碰在线免费观看97| 99re8这里有精品热视频免费 | 美女毛片在线观看| jlzzjlzz亚洲日本少妇| 乱子伦视频在线看| 天天揉久久久久亚洲精品| 国产传媒欧美日韩| 久久uomeier| 久久手机免费视频| 污污视频在线免费看| 欧美日韩在线一区二区| 久久一区二区三| 久久久久久久性| 97超碰人人看| 久久亚洲欧洲| 好吊色这里只有精品| 台湾色综合娱乐中文网| 成人av在线网址| 樱花草涩涩www在线播放| 久久夜精品香蕉| 精品无吗乱吗av国产爱色| 欧美精品xxxxbbbb| 一级片中文字幕| 亚洲精品福利视频网站| 国产av自拍一区| 国产福利电影一区二区三区| 日日碰狠狠丁香久燥| 黄页网站一区| 一区二区日本| 蜜桃a∨噜噜一区二区三区| 亚洲淫片在线视频| 78精品国产综合久久香蕉| 国产做受69高潮| 好了av在线| 曰本色欧美视频在线| 天天色综合av| 欧美成人午夜电影| 亚洲天堂网视频| 日本电影亚洲天堂一区| 国产精彩视频在线| 亚洲精品日韩综合观看成人91| av电影在线不卡| 99久久er热在这里只有精品15 | 成人高清伦理免费影院在线观看| 波多野结衣一区二区| 一区二区三区四区不卡视频| 亚洲一区视频在线播放| 播五月开心婷婷综合| 男人操女人下面视频| 免费视频最近日韩| 黄色一级一级片| 亚洲国产日本| 日本aa在线观看| 亚洲欧美日韩高清在线| 亚洲永久激情精品| 国产日产精品一区二区三区四区的观看方式 | 免费看黄色aaaaaa 片| 国产激情一区二区三区| 在线能看的av网站| 毛片基地黄久久久久久天堂| 五月婷婷狠狠操| 天堂成人国产精品一区| 精品久久久久久久免费人妻| 久久不射2019中文字幕| 国产特级淫片高清视频| 亚洲三级国产| 男人和女人啪啪网站| 亚洲国产精品第一区二区| 日本一本中文字幕| 在线观看亚洲| 男女视频网站在线观看| 亚洲国产激情| 欧美成人xxxxx| 香蕉久久国产| 国产成人精品视频ⅴa片软件竹菊| 天堂蜜桃一区二区三区| 天天色综合天天色| 美国毛片一区二区三区| 特黄视频免费观看| 国产综合色精品一区二区三区| 老司机午夜性大片| 国产麻豆视频一区| 一级全黄裸体片| av在线播放一区二区三区| 艳妇乳肉亭妇荡乳av| 91美女蜜桃在线| 国产精品国产三级国产专业不| 国产日韩精品久久久| 小嫩苞一区二区三区| 亚洲视频在线一区| 国产污视频在线观看| 欧美天天综合色影久久精品| 69xxxx国产| 欧美精品丝袜久久久中文字幕| 国产特级aaaaaa大片| 精品国产99国产精品| 欧美捆绑视频| 日韩在线观看成人| 男女在线视频| 欧洲成人在线观看| 欧美性www| 国产嫩草一区二区三区在线观看| 亚洲日本三级| 日本久久高清视频| 亚洲免费网址| 国产欧美一区二| 97久久精品人人澡人人爽| 国产三级黄色片| 夜夜亚洲天天久久| 免费一级a毛片| 日韩欧美国产三级| 东凛在线观看| 欧美精品18videos性欧| av在线日韩| 国产高清不卡av| 精品国产乱码久久久| 伊人网在线免费| 日本亚洲天堂网| 国产精品久久久久久亚洲色| 国产精品久线在线观看| 国产成人在线免费观看视频| 欧美日韩国产精品自在自线| 免费a级片在线观看| 在线免费观看羞羞视频一区二区| 亚洲h片在线看| 国产精品亚洲综合天堂夜夜| 久久综合另类图片小说| 在线视频不卡一区二区三区| 日韩一级不卡| 99热这里只有精品2| 国产免费成人在线视频| 精品午夜福利视频| 欧美剧情电影在线观看完整版免费励志电影 | 成人av资源网| 久久影院100000精品| 欧美视频在线播放一区| 国产成人一区二区精品非洲| 国产7777777| 日韩欧中文字幕| 免费a级片在线观看| 久久97久久97精品免视看| 激情小说亚洲| 欧美一区少妇| 国产精品一二| 亚洲av永久无码精品| 亚洲女子a中天字幕| 中文字幕乱码在线观看| 亚洲欧美另类人妖| 高清在线视频不卡| 成人激情直播| 女主播福利一区| 伊人色在线视频| 国产精品人成在线观看免费| 精品一区二区无码| 亚洲欧洲黄色网| 在线天堂中文资源最新版| 国产91亚洲精品一区二区三区| 亚洲精品va| 天堂网成人在线| 自拍av一区二区三区| 国产一区二区三区黄片| 综合网日日天干夜夜久久| 国产极品久久久久久久久波多结野| 女女同性女同一区二区三区91 | 免费无码av片在线观看| 成人少妇影院yyyy| 久久网一区二区| 亚洲国产精品999| 超碰在线99| 精品毛片久久久久久| 国产精品久久久亚洲一区| 懂色av粉嫩av蜜乳av| 色综合天天综合在线视频| 免费一级在线观看| 国产精品高潮在线| 久久蜜桃av| 日韩a一级欧美一级| 亚洲综合无码一区二区| 欧洲精品久久一区二区| 国外色69视频在线观看| 欧美一区二区三区久久| 久久国产色av免费观看| 国产精品美女久久久久aⅴ| 91极品身材尤物theporn| 久久不射电影网| 国产乱论精品| 欧美一级片中文字幕| 国产精品视频免费| 精品二区在线观看| 久久久亚洲福利精品午夜| 色婷婷av一区二区三区丝袜美腿| 97在线免费公开视频| 国产精品乱子久久久久| www.黄色国产| 国产91精品久久久久| 欧美日韩水蜜桃| 亚洲男人天堂2021| 午夜精品久久久久影视| av在线天堂播放| 91蜜桃网站免费观看| 国产亚洲精品v| 亚洲色图第四色| 欧美一区二区三区在| 欧美aa在线| 中文字幕一区二区三区在线乱码| 岛国精品在线观看| 无码人妻精品一区二区三区不卡| 久久精品国产精品| 欧美黑白配在线| 亚洲激情在线看|