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

解鎖Golang模板的力量:動態文本生成的初學者指南

開發 前端
Golang template提高代碼重用性:模板引擎允許你創建可重用的模板片段。通過將重復的模板邏輯提取到單獨的模板中,并在需要時進行調用,可以減少代碼重復,提高代碼的可維護性和可擴展性。

Golang Template

Go語言中的Go Template是一種用于生成文本輸出的簡單而強大的模板引擎。它提供了一種靈活的方式來生成各種格式的文本,例如HTML、XML、JSON等。

Go Template具有以下主要特性:

  1. 簡潔易用:Go Template語法簡潔而易于理解。它使用一對雙大括號“{{}}”來標記模板的占位符和控制結構。這種簡單的語法使得模板的編寫和維護變得非常方便。
  2. 數據驅動:Go Template支持數據驅動的模板生成。你可以將數據結構傳遞給模板,并在模板中使用點號“.”來引用數據的字段和方法。這種數據驅動的方式使得模板可以根據不同的數據動態生成輸出。
  3. 條件和循環:Go Template提供了條件語句和循環語句,使得你可以根據條件和迭代來控制模板的輸出。你可以使用“if”、“else”、“range”等關鍵字來實現條件判斷和循環迭代,從而生成靈活的輸出。
  4. 過濾器和函數:Go Template支持過濾器和函數,用于對數據進行轉換和處理。你可以使用內置的過濾器來格式化數據,例如日期格式化、字符串截斷等。此外,你還可以定義自己的函數,并在模板中調用這些函數來實現更復雜的邏輯和操作。
  5. 嵌套模板:Go Template支持模板的嵌套,允許你在一個模板中包含其他模板。這種模板的組合和嵌套機制可以幫助你構建更大型、更復雜的模板結構,提高代碼的可重用性和可維護性。

在很多Go開發的工具、項目都大量使用了template模板。例如: Helm,K8s,Prometheus,以及一些code-gen代碼生成器等等。Go template提供了一種模板機制,通過預聲明模板,傳入自定義數據來靈活定制各種文本。

1.示例

我們通過一個示例來了解一下template的基本使用。

首先聲明一段模板

var md = `Hello,{{ . }}`

解析模板并執行

func main() {
 tpl := template.Must(template.New("first").Parse(md))
 if err := tpl.Execute(os.Stdout, "Jack"); err != nil {
  log.Fatal(err)
 }
}

// 輸出
// Hello Jack

在上述例子中, {{ . }}前后花括號屬于分界符,template會對分界符內的數據進行解析填充。其中 .代表當前對象,這種概念在很多語言中都存在。

在main函數中,我們通過template.New創建一個名為"first"的template,并用此template進行Parse解析模板。隨后,再進行執行:傳入io.Writer,data,template會將數據填充至解析的模板中,再輸出到傳入的io.Writer上。

我們再來看一個例子

// {{ .xxoo -}} 刪除右側的空白
var md = `個人信息:
姓名: {{ .Name }}
年齡: {{ .Age }}
愛好: {{ .Hobby -}}
`

type People struct {
 Name string
 Age  int
}

func (p People) Hobby() string {
 return "唱,跳,rap,籃球"
}

func main() {

 tpl := template.Must(template.New("first").Parse(md))
 p := People{
  Name: "Jackson",
  Age:  20,
 }
 if err := tpl.Execute(os.Stdout, p); err != nil {
  log.Fatal(err)
 }
}

// 輸出
//個人信息:
//姓名: Jackson       
//年齡: 20            
//愛好: 唱,跳,rap,籃球

Hobby屬于People的方法,所以在模板中也可以通過.進行調用。需要注意: 不管是字段還是方法,由于template實際解析的包與當前包不同,無論是字段還是方法必須是導出的。

在template中解析時,它 移除了 {{ 和 }} 里面的內容,但是留下的空白完全保持原樣。所以解析出來的時候,我們需要對空白進行控制。YAML認為空白是有意義的,因此管理空白變得很重要。我們可以通過-進行控制空白。

{{- (包括添加的橫杠和空格)表示向左刪除空白, 而 -}}表示右邊的空格應該被去掉。

要確保-和其他命令之間有一個空格。

{{- 10 }}: "表示向左刪除空格,打印10"

{{ -10 }}: "表示打印-10"

2.流程控制

條件判斷 IF ELSE

在template中,提供了if/else的流程判斷。

我們看一下doc的定義:

{{if pipeline}} T1 {{end}}
 如果 pipeline 的值為空,則不生成輸出;
 否則,執行T1。空值為 false、0、任何
 nil 指針或接口值,以及
 長度為零的任何數組、切片、映射或字符串。
 點不受影響。
{{if pipeline}} T1 {{else}} T0 {{end}}
 如果 pipeline 的值為空,則執行 T0;
 否則,執行T1。點不受影響。
{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
 為了簡化 if-else 鏈的外觀,
 if 的 else 操作可以直接包含另一個 if

其中pipeline命令是一個簡單的值(參數)或一個函數或方法調用。我們第一個例子的hobby就屬于方法調用。

繼續是上面的案例,我們添加了一個IF/ELSE來判斷年齡,在IF中我們使用了一個內置函數gt判斷年齡。

在template中,調用函數,傳遞參數是跟在函數后面: function arg1 agr2。

或者也可以通過管道符進行傳遞:arg | function

每個函數都必須有1到2個返回值,如果有2個則后一個必須是error接口類型。

var md = `個人信息:
姓名: {{ .Name }}
年齡: {{ .Age }}
愛好: {{ .Hobby -}}
{{ if gt .Age 18 }}
成年人
{{ .Age | print }}
{{ else }}
未成年人
{{ end }}
`

// 輸出
//個人信息:
//姓名: Jackson       
//年齡: 20            
//愛好: 唱,跳,rap,籃球
//成年人              
//20

循環控制range

template同時也提供了循環控制的功能。我們還是先看一下doc

{range pipeline}} T1 {{end}} pipeline 的值必須是數組、切片、映射或通道。
 如果管道的值長度為零,則不輸出任何內容;
 否則,將點設置為數組的連續元素,
 切片或映射并執行 T1。如果值是映射并且鍵是具有定義順序的基本類型,則將按排序鍵順序訪問
 
{{range pipeline}} T1 {{else}} T0 {{end}} 
 pipeline 的值必須是數組、切片、映射或通道。
 如果管道的值長度為零,則 . 不受影響并
 執行 T0;否則,將 . 設置為數組、切片或映射的連續元素,并執行 T1。
 
{{break}}
 最里面的 {{range pipeline}} 循環提前結束,停止當前迭代并繞過所有剩余迭代。
 
{{continue}}
 最里面的 {{range pipeline}} 循環的跳過當前迭代

整合上面的IF/ELSE,我們做一個綜合案例

var md = `
Start iteration:
{{- range . }}
{{- if gt . 3 }}
超過3
{{- else }}
{{ . }}
{{- end }}
{{ end }}
`

func main() {
 tpl := template.Must(template.New("first").Parse(md))
 p := []int{1, 2, 3, 4, 5, 6}
 if err := tpl.Execute(os.Stdout, p); err != nil {
  log.Fatal(err)
 }
}

// 輸出
//1       
//2        
//3       
//超過3    
//超過3    
//超過3

我們通過{{ range . }}遍歷傳入的對象,在循環內部再通過{{ if }}/{{ else }}判斷每個元素的大小。

作用域控制with

在語言中都有一個作用域的概念。template也提供了通過使用with去修改作用域。

我們來看一個案例

var md = `
people name(out scope): {{ .Name }}
dog name(out scope): {{ .MyDog.Name }}
{{- with .MyDog }}
dog name(in scope): {{ .Name }} 
people name(in scope): {{ $.Name }}
{{ end }}
`
type People struct {
 Name  string
 Age   int
 MyDog Dog
}

type Dog struct {
 Name string
}

func main() {
 tpl := template.Must(template.New("first").Parse(md))
 p := People{Name: "Lucy", MyDog: Dog{Name: "Tom"}}
 if err := tpl.Execute(os.Stdout, p); err != nil {
  log.Fatal(err)
 }
}

// 輸出
//people name(out scope): Lucy
//dog name(out scope): Tom    
//dog name(in scope): Tom     
//people name(in scope): Lucy

在頂層作用域中,我們直接可以通過.去獲取對象的信息。在聲明的with中,我們將頂層對象的MyDog傳入,那么在with作用域中,通過.獲取的對象就是Dog。所以在with中我們可以直接通過.獲取Dog的name。

有些時候,在子作用域中我們可能也希望可以獲取到頂層對象,那么我們可以通過$獲取頂層對象。上述例子的$.獲取到People。

3.函數

在第二節內容中,我們使用了print,gt函數,這些函數都是預定義在template中。我們通過查閱源碼可以查看預定義了以下函數:

func builtins() FuncMap {
 return FuncMap{
  "and":      and,
  "call":     call,
  "html":     HTMLEscaper,
  "index":    index,
  "slice":    slice,
  "js":       JSEscaper,
  "len":      length,
  "not":      not,
  "or":       or,
  "print":    fmt.Sprint,
  "printf":   fmt.Sprintf,
  "println":  fmt.Sprintln,
  "urlquery": URLQueryEscaper,

  // Comparisons
  "eq": eq, // ==
  "ge": ge, // >=
  "gt": gt, // >
  "le": le, // <=
  "lt": lt, // <
  "ne": ne, // !=
 }
}

在實際開發中,僅僅是這些函數是很難滿足我們的需求。此時,我們希望能夠傳入自定義函數,在我們編寫模板的時候可以使用自定義的函數。

我們引入一個需求: 希望將傳入的str可以轉為小寫。

var md = `
result: {{ . | lower }}
`

func Lower(str string) string {
 return strings.ToLower(str)
}

func main() {
 tpl := template.Must(template.New("demo").Funcs(map[string]any{
  "lower": Lower,
 }).Parse(md))
 tpl.Execute(os.Stdout, "HELLO FOSHAN")
}

// 輸出
// result: hello foshan

由于template支持鏈式調用,所以我們一般把Parse放在最后

我們通過調用Funcs,傳入functionName : function的map。

執行模板時,函數從兩個函數map中查找:首先是模板函數map,然后是全局函數map。一般不在模板內定義函數,而是使用Funcs方法添加函數到模板里。

方法必須有一到兩個返回值,如果是兩個,那么第二個一定是error接口類型

注意:Funcs必須在解析parse前調用。如果模板已經解析了,再傳入funcs,template并不知道該函數應該如何映射。

4.變量

函數、管道符、對象和控制結構都可以控制,我們轉向很多編程語言中更基本的思想之一:變量。在模板中,很少被使用。但是我們可以使用變量簡化代碼,并更好地使用with和range。

我們通過{{ $var := .Obj }}聲明變量,在with/range中我們使用的會比較頻繁

var md = `
{{- $count := len . -}}
共有{{ $count }}個元素
{{- range $k,$v := . }}
{{ $k }} => {{ $v }}
{{- end }}
`

func main() {
 tpl := template.Must(template.New("demo").Parse(md))
 tpl.Execute(os.Stdout, map[string]string{
  "p1": "Jack",
  "p2": "Tom",
  "p3": "Lucy",
 })
}

// 輸出
// 共有3個元素
// p1 => Jack 
// p2 => Tom  
// p3 => Lucy

{{ var }}聲明的變量也有作用域的概念,如果在頂層作用域中聲明了var,那么在內部作用域可以直接通過獲取該變量

我們通過{{- range $k,$v := . }}遍歷map中每一個KV,這種寫法類似于Golang的for-range。

5.命名模板

在Go語言的模板引擎中,命名模板是指通過給模板賦予一個唯一的名稱,將其存儲在模板集中,以便后續可以通過該名稱來引用和執行該模板。

通過使用命名模板,你可以將一組相關的模板邏輯組織在一起,并在需要的時候方便地調用和重用它們。這對于構建復雜的模板結構和提高模板的可維護性非常有用。

在編寫復雜模板的時候,我們總是希望可以抽象出公用模板,那么此時就需要使用命名模板進行復用。

本節將基于K8sPod模板的案例來學習如何使用命名模板進行抽象復用。

我們看一下doc

{{template "name"}}
 具有指定名稱的模板以無數據執行。

{{template "name" pipeline}}
 具有指定名稱的模板以pipeline結果執行。

通過define定義模板名稱

{{ define "container" }}
 模板
{{ end }}

通過template使用模板

{{ template "container" }}

我們在使用template.New傳入的name,實際上就是定義了模板的名稱

案例:我們希望抽象出Pod的container,通過代碼來傳入數據生成container,避免重復的編寫yaml。

var pod = `
apiVersion: v1
kind: Pod
metadata:
  name: "test"
spec:
  containers:
{{- template "container" .}}
`
var container = `
{{ define "container" }}
    - name: {{ .Name }}
      image: "{{ .Image}}"
{{ end }}
`

func main() {
 tpl := template.Must(template.New("demo").Parse(pod))
 tpl.Parse(container)
 tpl.ExecuteTemplate(os.Stdout, "demo", struct {
  Name  string
  Image string
 }{
  "nginx",
  "1.14.1",
 })
}

// 輸出
apiVersion: v1
kind: Pod
metadata:
  name: "test"
spec:
  containers:
    - name: nginx    
      image: "1.14.1"

tpl可以解析多個模板,在不同模板中通過define定義模板即可。使用ExecuteTemplate傳入模板名指定解析模板。在{{- template "container" .}}中可以傳入對象數據。

在實際開發中,我們往往不會采用打印的方式輸出。可以根據不同的需求,在Execute執行時選擇不同的io.Writer。往往我們更希望寫入到文件中。

6.Template常用函數

func Must(t *Template, err error) *Template

Must是一個helper函數,它封裝對返回(Template, error)的函數的調用,并在錯誤非nil時panic。它旨在用于template初始化。

// 解析指定文件
// 示例: ParseFiles(./pod.tpl) 
func ParseFiles(filenames ...string) (*Template, error)


// 解析filepath.Match匹配文件
// 示例: ParseGlob(/data/*.tpl)
func ParseGlob(pattern string) (*Template, error)

這兩個函數幫助我們解析文件中的模板,大多數情況下我們都是將模板寫在.tpl結尾的文件中。通過不同的解析規則解析對應的文件。

func (t *Template) Templates() []*Template

返回當前t相關的模板的slice,包括t本身。

func (t *Template) ExecuteTemplate(wr io.Writer, name string, data any) error

傳入模板名稱,執行指定的模板。

如果在執行模板或寫入其輸出時發生錯誤,執行將停止,但部分結果可能已經被寫入輸出寫入器。模板可以安全地并行執行,但如果并行執行共享一個Writer,則輸出可能交錯。

func (t *Template) Delims(left, right string) *Template

修改模板中的分界符,可以將{{}}修改為<>

func (t *Template) Clone() (*Template, error)

clone返回模板的副本,包括所有關聯模板。在clone的副本上添加模板是不會影響原始模板的。所以我們可以將其用于公共模板,通過clone獲取不同的副本。

7.總結

Golang template提高代碼重用性:模板引擎允許你創建可重用的模板片段。通過將重復的模板邏輯提取到單獨的模板中,并在需要時進行調用,可以減少代碼重復,提高代碼的可維護性和可擴展性。有許多code-gen使用了template + cobra方式生成復用代碼和模板代碼,有利于我們解放雙手。

原文鏈接:https://juejin.cn/post/7255189463746953271

本文轉載自微信公眾號「 程序員升級打怪之旅」,作者「 Shyunn&王中陽Go」,可以通過以下二維碼關注。

轉載本文請聯系「 程序員升級打怪之旅」公眾號。

責任編輯:武曉燕 來源: 程序員升職加薪之旅
相關推薦

2024-08-07 10:18:00

2022-04-24 15:21:01

MarkdownHTML

2022-10-10 15:28:45

負載均衡

2010-06-13 11:13:38

UML初學者指南

2022-07-22 13:14:57

TypeScript指南

2010-08-26 15:47:09

vsftpd安裝

2018-10-28 16:14:55

Reactreact.js前端

2021-05-10 08:50:32

網絡管理網絡網絡性能

2023-07-03 15:05:07

預測分析大數據

2023-07-28 07:31:52

JavaScriptasyncawait

2022-03-28 09:52:42

JavaScript語言

2021-05-06 09:00:00

JavaScript靜態代碼開發

2024-12-25 08:00:00

機器學習ML管道人工智能

2022-09-05 15:36:39

Linux日志記錄syslogd

2012-03-14 10:56:23

web app

2023-02-10 08:37:28

2023-04-18 15:15:06

神經網絡激活函數開發

2022-01-21 09:05:34

機器學習工具安全

2020-07-29 08:26:40

Webpack前端模塊

2023-07-30 14:56:42

ReactJavaScript開發
點贊
收藏

51CTO技術棧公眾號

国产小视频在线播放| 青青草免费av| 欧美成人精品一区二区男人小说| 91免费在线播放| 全亚洲最色的网站在线观看| 国产不卡在线观看视频| www.欧美视频| 午夜在线视频一区二区区别| 亚洲另类xxxx| 污污网站免费观看| 黄网av在线| 亚洲国产高清aⅴ视频| 91在线播放视频| 国产嫩bbwbbw高潮| 日韩五码电影| 午夜国产不卡在线观看视频| 视频一区视频二区视频三区视频四区国产 | 99视频免费观看| 欧美brazzers| 久久香蕉网站| 欧美日韩免费一区二区三区 | 免费在线观看一级毛片| 欧美日韩亚洲一区三区| 亚洲美女激情视频| 男人的天堂免费| 国产精品黄色片| 欧美日韩免费看| 成人免费看片'免费看| av资源网站在线观看| 91在线porny国产在线看| 亚洲a区在线视频| 亚洲婷婷久久综合| 亚洲欧美卡通另类91av| 欧美激情啊啊啊| 人人干在线观看| 国产一区二区三区日韩精品| 亚洲精品电影网站| 中文字幕天堂av| 99riav视频在线观看| 综合av第一页| 在线免费观看成人| av中文字幕免费| 免费成人美女在线观看| 4438全国成人免费| 久久久久久国产精品无码| 亚洲国产高清在线观看| 9191国产精品| 毛片毛片毛片毛| 日韩国产大片| 欧美久久久久久蜜桃| 日韩不卡一二三| 欧美成a人片免费观看久久五月天| 色av综合在线| 国产一级特黄a大片免费| 91久久国产综合久久91猫猫| 精品国产乱码久久久久酒店| 亚洲中文字幕无码av永久| a级片在线免费| 图片区小说区国产精品视频| 日韩黄色短视频| av电影在线地址| 五月婷婷综合网| 久久久噜噜噜www成人网| videos性欧美另类高清| 在线日韩一区二区| 手机av在线网| 亚洲视频一起| 日韩国产精品亚洲а∨天堂免| 亚洲自拍偷拍精品| 日韩理论电影中文字幕| 亚洲人免费视频| 欧美成人另类视频| 香蕉国产精品| 亚洲另类图片色| 中文字幕免费高清| 欧美xxxx中国| 欧美人与性动交| 五月婷婷中文字幕| 日本一不卡视频| 51国偷自产一区二区三区的来源| 亚洲av永久纯肉无码精品动漫| 成人av电影免费观看| 免费国产在线精品一区二区三区| 一级α片免费看刺激高潮视频| 日本特黄久久久高潮| 91香蕉电影院| 手机看片国产1024| 国产欧美日韩麻豆91| 一区二区三区欧美在线| 欧美黑人xx片| 在线观看欧美日本| 手机在线观看日韩av| 色综合天天色| 欧美一级搡bbbb搡bbbb| 欧美婷婷精品激情| 日韩一区二区三区在线看| 日韩av在线免播放器| 在线观看天堂av| 中文久久精品| 欧美激情视频一区二区| 少妇高潮av久久久久久| 国产精品一区二区果冻传媒| 久久综合给合久久狠狠色| 免费高清完整在线观看| 欧美日韩一区二区在线播放| 亚洲第一天堂久久| 国产免费播放一区二区| 欧美激情日韩图片| 中文字幕自拍偷拍| 99久久99久久综合| 热久久最新地址| 成人免费毛片嘿嘿连载视频…| 精品国一区二区三区| 自拍偷拍你懂的| 欧美资源在线| 国产综合色一区二区三区| 国产三区视频在线观看| 亚洲码国产岛国毛片在线| 激情综合在线观看| 成人香蕉社区| 亚洲黄一区二区| 疯狂试爱三2浴室激情视频| 麻豆精品网站| 国产成人精品一区二区三区福利 | 91综合精品国产丝袜长腿久久| 在线播放日韩av| 国产又黄又猛又粗又爽| 成人性视频网站| 99视频精品全部免费看| 国外成人福利视频| 亚洲性视频网站| 在线观看日本网站| 91看片淫黄大片一级| 久久亚洲精品无码va白人极品| 欧美日本三级| 美女av一区二区| 91尤物国产福利在线观看| 国产天堂亚洲国产碰碰| 欧美 日韩 国产一区| 国产三级精品三级在线观看国产| 精品中文字幕在线2019| 国产福利第一视频| 一级特黄大欧美久久久| 性一交一黄一片| 欧美日韩午夜| 国产伦精品一区二区三区高清版| 午夜成年人在线免费视频| 91精品国产综合久久久久| 日韩成人短视频| 国产精品白丝jk黑袜喷水| 水蜜桃在线免费观看| 精品国产一区二区三区性色av| 久久综合久久88| 99国产揄拍国产精品| 夜夜嗨av一区二区三区中文字幕| 黑人无套内谢中国美女| 欧美a级片一区| 国产精品.com| 亚洲人成在线网站| 国产亚洲人成a一在线v站| 中文字幕免费视频观看| 国产精品久久久爽爽爽麻豆色哟哟| www.99av.com| 亚洲五月综合| 97视频免费在线观看| 日本黄色三级视频| 国产精品你懂的| 不卡的在线视频| 欧美精品偷拍| 激情视频在线观看一区二区三区| 国产精品伦理| 日韩三级成人av网| 亚洲男人第一天堂| 色综合天天在线| 国产一区二区三区视频播放| 国产乱码一区二区三区| 国产美女网站在线观看| 精品一区电影| 亚洲专区中文字幕| 麻豆理论在线观看| 日韩一级裸体免费视频| 亚洲国产视频一区二区三区| 日韩欧美一区二区三区久久| 特黄一区二区三区| 99久久精品费精品国产一区二区| 又色又爽又高潮免费视频国产| 国产韩日影视精品| 狠狠干一区二区| 日本午夜精品久久久久| 国内精品一区二区三区| 最新97超碰在线| 亚洲国产精品网站| 一二三区中文字幕| 精品久久久久久久久中文字幕| 特黄一区二区三区| 久久午夜免费电影| 男插女视频网站| 日韩专区中文字幕一区二区| 国产在线精品一区二区中文| 日韩国产网站| 久久免费国产视频| 毛片在线视频| 亚洲全黄一级网站| 成人久久精品人妻一区二区三区| 欧美亚一区二区| 日韩特黄一级片| 亚洲三级理论片| 视色视频在线观看| 亚洲人体大胆视频| 成年人免费观看的视频| 麻豆视频在线观看免费网站黄| 国产亚洲精品激情久久| 可以免费观看的毛片| 欧美日韩在线观看一区二区| 99久在线精品99re8热| 亚洲欧美日韩国产成人精品影院| 精品少妇人妻一区二区黑料社区| 丰满放荡岳乱妇91ww| 三日本三级少妇三级99| 日本人妖一区二区| 成人久久久久久久久| 黑丝一区二区| 2022中文字幕| 91精品亚洲| 中文字幕一区二区三区最新| 国产成人精品免费视| 精品一区二区久久久久久久网站| 欧美三级一区| 91久久精品国产91性色| 欧美成人毛片| 国产精品欧美日韩久久| 亚洲www啪成人一区二区| 日韩av不卡电影| 天堂а√在线最新版中文在线| 欧美第一黄色网| 污污网站在线观看| 欧美乱妇高清无乱码| 日本www在线观看| 日韩在线播放一区| 欧美激情黑人| 美日韩丰满少妇在线观看| 拍真实国产伦偷精品| 日韩中文字幕在线| 午夜激情在线观看| 久久精品免费播放| www久久日com| 久久6免费高清热精品| 羞羞污视频在线观看| 欧美日韩高清区| 国产精品蜜臀| 2019中文字幕免费视频| 亚洲免费福利| 国产精品女人久久久久久| 国产精品原创视频| 91亚洲精品久久久久久久久久久久| 欧美性aaa| 97视频资源在线观看| 一区二区三区在线免费看| 国产精品一区二区三区四区五区| 九色丨蝌蚪丨成人| 免费看成人av| 日韩精品二区| 欧美日韩中文字幕在线播放| 亚洲特级毛片| 国产精品69页| 久久爱www久久做| 性一交一乱一伧国产女士spa| 欧美日韩国产亚洲一区| www.99热这里只有精品| 性色一区二区三区| 视频二区在线播放| 国产成人午夜视频| 醉酒壮男gay强迫野外xx| 欧美激情中文不卡| 欧美人妻精品一区二区免费看| 亚洲国产裸拍裸体视频在线观看乱了 | 亚洲精品国产一区二| 亚洲精品电影在线观看| av资源种子在线观看| 欧美国产极速在线| 日韩精品一区二区三区| 成人网址在线观看| 国产精欧美一区二区三区蓝颜男同| 国产精品对白刺激| 在线天堂中文资源最新版| 国产精品欧美一区二区| 我要色综合中文字幕| 狼狼综合久久久久综合网| 99精品美女| 97国产在线播放| 精品亚洲porn| 亚洲第一色av| 99久久综合精品| 少妇熟女视频一区二区三区| 91香蕉视频在线| 国产色无码精品视频国产| 婷婷综合在线观看| 一本一道精品欧美中文字幕| 亚洲精品久久久久久久久久久久久| 午夜小视频在线| 4p变态网欧美系列| 日韩欧美另类中文字幕| 日本高清视频一区二区三区| 欧美激情一级片一区二区| 免费看a级黄色片| 暴力调教一区二区三区| 天天操夜夜操av| 色丁香久综合在线久综合在线观看| a级片免费视频| 在线观看国产精品淫| 欧美xxxhd| 国产高清精品一区| 午夜精品一区二区三区国产| 成年人免费大片| 成人午夜看片网址| 高h视频免费观看| 欧美日韩国产小视频在线观看| 男人天堂网在线| 97视频在线观看网址| 涩爱av色老久久精品偷偷鲁| 一本久道久久综合狠狠爱亚洲精品| 亚洲影院一区| 中文字幕一区三区久久女搜查官| 伊人夜夜躁av伊人久久| 一二三区中文字幕| 日韩亚洲成人av在线| 国产一区二区主播在线| 欧美久久久久久| 亚洲影院一区| 91精品人妻一区二区三区| 欧美日韩国产精品专区| 国产激情视频在线播放 | 成人高潮免费视频| 欧美三级一区二区| 北岛玲一区二区三区| 国产激情综合五月久久| 精品国产99| 天堂av在线网站| 中文在线免费一区三区高中清不卡 | 国产精品v日韩精品v欧美精品网站 | 91在线视频国产| 色偷偷91综合久久噜噜| 欧美黄页在线免费观看| 亚洲三区在线| 黄色小说综合网站| 欧美黑吊大战白妞| 欧美mv日韩mv国产网站app| 日本大片在线播放| 国产欧美一区二区在线播放| 亚洲人成毛片在线播放女女| 亚洲色图14p| 欧美午夜精品久久久久久浪潮| 亚洲av片在线观看| 欧美在线亚洲在线| 日本一区二区在线看| 亚洲一二三不卡| 亚洲综合色网站| 亚洲AV第二区国产精品| 国产成人亚洲综合91精品| 成人在线免费观看视频| 交换做爰国语对白| 亚洲第一主播视频| 日韩午夜影院| www亚洲精品| 成人豆花视频| 久久亚洲精品无码va白人极品| 99免费精品在线观看| 久久久蜜桃一区二区| www国产91| 卡通动漫国产精品| 黄色成人免费看| 亚洲欧美另类综合偷拍| 日本高清视频网站| 国产精品视频一区国模私拍| 91精品国产自产拍在线观看蜜| 日本50路肥熟bbw| 日本高清成人免费播放| 日本免费中文字幕在线| 国产精品中出一区二区三区| 久久久精品五月天| 国产黄色录像片| 亚洲精品在线观看www| 日韩一级特黄| av免费观看网| 综合精品久久久| 欧洲伦理片一区 二区 三区| 成人黄色午夜影院| 国产精品久久久久9999高清| 少妇的滋味中文字幕bd| 亚洲国产精品99| 视频在线观看入口黄最新永久免费国产 | 毛葺葺老太做受视频| 亚洲精品欧美激情| 国产中文字幕在线播放| 98国产高清一区| 日韩av在线播放中文字幕| www.youjizz.com亚洲| 中文字幕亚洲综合久久筱田步美| 在线播放一区二区精品视频| 超碰在线人人爱|