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

Go中這么多創(chuàng)建Error的方式,你真的了解它們各自的應(yīng)用場景嗎

開發(fā) 前端
本文從應(yīng)用場景的角度講解了各種創(chuàng)建錯誤方式的實際應(yīng)用場景。示例中的代碼盡量的選自golang源碼或開源項目。同時,每種的應(yīng)用場景并非絕對的,需要靈活應(yīng)用。希望本文對大家在實際使用中能夠有所幫助。

大家好,我是漁夫子。今天從應(yīng)用場景的角度來聊聊我對error的理解。

01 什么是Error

在Go中,error是一種內(nèi)建的數(shù)據(jù)類型,被定義為一個接口,定義如下:

// The error built-in interface type is the conventional interface for
// representing an error condition, with the nil value representing no error.
type error interface {
	Error() string
}

由此可知,該接口只有一個返回字符串的Error函數(shù),所有的類型只要實現(xiàn)了該函數(shù),就創(chuàng)建了一個錯誤類型。

02 創(chuàng)建error的方式

創(chuàng)建error的方式包括errors.New、fmt.Errorf、自定義實現(xiàn)了error接口的類型等。

2.1 通過errors.New方法創(chuàng)建

通過該方法創(chuàng)建的錯誤一般是可預(yù)知的錯誤。簡單來說就是調(diào)用者通過該錯誤信息就能明確的知道哪里出錯了,而不需要再額外的添加其他上下文信息,我們在下面的示例中詳細(xì)說明。

err := errors.New("this is error")

我們看New方法的實現(xiàn)可知,實際上是返回了一個errorString結(jié)構(gòu)體,該結(jié)構(gòu)體包含了一個字符串屬性,并實現(xiàn)了Error方法。代碼如下:

func New(text string) error {
	return &errorString{text}
}

// errorString is a trivial implementation of error.
type errorString struct {
	s string
}

func (e *errorString) Error() string {
	return e.s
}

error.New 使用場景1

通過errors.New函數(shù)創(chuàng)建局部變量或匿名變量,且不在調(diào)用函數(shù)中進(jìn)行值或類型判斷的處理,只打印或記錄錯誤日志的場景。

使用示例1

以下代碼節(jié)選自源碼/src/net/http/request.go中解析PostForm的部分。當(dāng)請求中的Body為nil時,返回的錯誤信息是"missing form body"。該信息已明確的說明錯誤是因為請求體為空造成的,所以不需要再額外的添加其他上下文信息。

func parsePostForm(r *Request) (vs url.Values, err error) {
	if r.Body == nil {
		err = errors.New("missing form body")
		return
	}
	ct := r.Header.Get("Content-Type")
	// 省略了后續(xù)的代碼...
	return
}

使用示例2

以下代碼節(jié)選自源碼/src/net/http/transport.go的部分,當(dāng)請求體中的url地址為nil返回的錯誤:"http: nil Request.URL" ,說明是請求中的URL字段為nil。以及當(dāng)Header為nil返回的錯誤:"http:nil Request.Header",說明請求體中的Header字段為nil。

func (t *Transport) roundTrip(req *Request) (*Response, error) {
	t.nextProtoOnce.Do(t.onceSetNextProtoDefaults)
	ctx := req.Context()
	trace := httptrace.ContextClientTrace(ctx)

	if req.URL == nil {
		req.closeBody()
		return nil, errors.New("http: nil Request.URL")
	}
	if req.Header == nil {
		req.closeBody()
		return nil, errors.New("http: nil Request.Header")
	}
	//省略后面的代碼...
}

error.New 使用場景2

將errors.New創(chuàng)建的錯誤賦值給一個全局的變量,我們稱該變量為哨兵錯誤,該哨兵錯誤變量可以在被處理的時候使用 == 或 errors.Is來進(jìn)行值的比較。

使用示例

在源碼/src/io/io.go中定義的代表文件末尾的哨兵錯誤變量EOF。

var EOF = errors.New("EOF")

在beego項目中,beego/core/utils/file.go文件中有這樣的應(yīng)用,當(dāng)讀取文件時,遇到的錯誤不是文件末尾的錯誤則直接返回,如果遇到的是文件末尾的錯誤,則中斷for循環(huán),說明文件已經(jīng)讀完文件中的所有內(nèi)容了。如下:

func GrepFile(patten string, filename string) (lines []string, err error) {
	//省略前面的代碼...
	
	fd, err := os.Open(filename)
	if err != nil {
		return
	}
	
	reader := bufio.NewReader(fd)
	for {
		byteLine, isPrefix, er := reader.ReadLine()
		if er != nil && er != io.EOF {
			return nil, er
		}
		if er == io.EOF {
			break
		}
		//省略后面的代碼...
	}

2.2 通過fmt.Errorf方法創(chuàng)建

該方法也有兩種形式,一種是帶%w占位符的,一種是不帶%w占位符的方式。

使用場景1:不帶%w占位符

在創(chuàng)建錯誤的時候,不能通過errors.New創(chuàng)建的字符串信息來描述錯誤,而需要通過占位符添加更多的上下文信息,即動態(tài)信息。

使用示例:不帶%w占位符

以下代碼節(jié)選自gorm/schema/relationship.go的部分代碼,當(dāng)外鍵不合法時,通過fmt.Errorf("invalid foreign key:%s", foreignKey)返回帶具體外鍵的錯誤。因為外鍵值是在運行時才能確定的。代碼如下:

func (schema *Schema) buildMany2ManyRelation(relation *Relationship, field *Field, many2many string) {
	//...
	
	if len(relation.foreignKeys) > 0 {
		ownForeignFields = []*Field{}
		for _, foreignKey := range relation.foreignKeys {
			if field := schema.LookUpField(foreignKey); field != nil {
				ownForeignFields = append(ownForeignFields, field)
			} else {
				schema.err = fmt.Errorf("invalid foreign key: %s", foreignKey)
				return
			}
		}
	}
	//...
}

使用場景2:帶%w占位符

在有些場景下,調(diào)用者需要知道原始錯誤信息,這時就需要使用帶%w占位符的fmt.Errorf方式來創(chuàng)建錯誤,使用這種方式,其實是形成了一個錯誤鏈。

其用法如下:

filename := "abc.webp"
fmt.Errorf("%w:%s", errors.New("unsupported extension"), filename)

我們再來看下源代碼:

func Errorf(format string, a ...interface{}) error {
	p := newPrinter()
	p.wrapErrs = true
	p.doPrintf(format, a)
	s := string(p.buf)
	var err error
	if p.wrappedErr == nil {
		err = errors.New(s)
	} else {
		err = &wrapError{s, p.wrappedErr}
	}
	p.free()
	return err
}

通過源碼可知,如果fmt.Errorf中包含%w占位符,創(chuàng)建的是一個wrapError結(jié)構(gòu)體類型的值。我們再來看下wrapError結(jié)構(gòu)體的定義:

type wrapError struct {
	msg string
	err error
}

字段err就是原始錯誤,msg是經(jīng)過格式化之后的錯誤信息。

使用示例:帶%w占位符

假設(shè)我們有一個從數(shù)據(jù)庫查詢合同的函數(shù),當(dāng)從數(shù)據(jù)庫中查詢到記錄為空時,會返回一個sql.ErrNoRows錯誤,我們用%w占位符來wrap該錯誤,并返回給調(diào)用者。

const query = "..."
func (s Store) GetContract(name string) (Contract, error) {
	id := getID(name)
	rows, err := s.db.Query(query, id)
	if err != nil {
		if err == sql.ErrNoRows {
			return Contract{},
			fmt.Errorf("no contract found for %s: %w", name, err) 
		}
		// ...
	}
	// ...
}

好了,現(xiàn)在GetContract的調(diào)用者可以知道原始的錯誤信息了。在調(diào)用者邏輯中我們可以使用errors.Is來判斷err中是否包含sql.ErrNoRows值了。我們看下調(diào)用者的代碼:

contract, err := store.GetContract("Raul Endymion")
if err != nil {
	if errors.Is(err, sql.ErrNoRows) { 
		// Do something specific
	}
}

2.3 自定義實現(xiàn)了error接口的結(jié)構(gòu)體

使用場景

這個是相對errors.New來說的,errors.New適用于對可預(yù)知的錯誤的定義。而當(dāng)發(fā)生了不可預(yù)知的錯誤時,就需要自定義錯誤類型了。

使用示例

我們以go中/src/io/fs/fs.go文件中的源碼為例,來看下自定義錯誤類型都需要包含哪些元素。

// PathError records an error and the operation and file path that caused it.
type PathError struct {
	Op   string
	Path string
	Err  error
}

func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() }

func (e *PathError) Unwrap() error { return e.Err }

首先看結(jié)構(gòu)體,有一個error接口類型的Err,這個代表的是錯誤源,因為根據(jù)上面講解的,在錯誤層層傳遞返回給調(diào)用者時,我們需要追蹤每一層的原始錯誤信息,所以需要該字段對error進(jìn)行wrap,形成錯誤鏈。另外,有兩個字段Op和Path,分別代表是產(chǎn)生該錯誤的操作和操作的路徑。這兩個字段就是所謂的未預(yù)料到的錯誤:不確定是針對哪個路徑做了什么錯誤引發(fā)了該錯誤。

我們看下該錯誤類型在代碼中的應(yīng)用。

應(yīng)用1:在go的文件src/embed/embed.go中的代碼,當(dāng)讀取某目錄時返回的一個PathError類型的錯誤,代表讀取該目錄操作時,因為是一個目錄,所以不能直接讀取文件內(nèi)容。

func (d *openDir) Read([]byte) (int, error) {
	return 0, &fs.PathError{Op: "read", Path: d.f.name, Err: errors.New("is a directory")}
}

應(yīng)用2:在go的文件src/embed/embed.go中的代碼中,有文件讀取的函數(shù),當(dāng)offset小于0時,返回了一個PathError,代表是在讀取該文件的時候,參數(shù)不正確。

func (f *openFile) Read(b []byte) (int, error) {
	if f.offset >= int64(len(f.f.data)) {
		return 0, io.EOF
	}
	if f.offset < 0 {
		return 0, &fs.PathError{Op: "read", Path: f.f.name, Err: fs.ErrInvalid}
	}
	n := copy(b, f.f.data[f.offset:])
	f.offset += int64(n)
	return n, nil
}

fs.ErrInvalid的定義如下

ErrInvalid    = errors.New("invalid argument")

由此可見,PathError中的三個字段值都是不可預(yù)知的,都需要在程序運行時才能具體決定的,所以這種場景時,則需要自定義錯誤類型。

另外,我們還注意到該自定義的類型中有Unwrap函數(shù)的實現(xiàn),該函數(shù)主要是為了配合errors.Is和errors.As使用的,因為這兩個函數(shù)在使用時是將錯誤鏈層層解包一一比對的。

03 errors.Is和errors.As

根據(jù)上一節(jié)我們得到,通過%w占位符可以將錯誤組織成一個錯誤鏈。我們再來看看通過errors.Is和errors.As如何處理被wrap過的錯誤鏈。

errors.Is函數(shù)就是來判斷錯誤鏈中有沒有和指定的錯誤值相等的錯誤,相當(dāng)于 == 操作符。注意,這里是特定的錯誤值,就像gorm中定義的ErrRecordNotFound這樣:

var ErrRecordNotFound = errors.New("record not found")

那么我們就可以這樣使用errors.Is:

errors.Is(err, ErrRecordNotFound)

errors.As函數(shù),該函數(shù)是用來檢查錯誤鏈中的錯誤是否有指定的錯誤類型的。

如下代碼示例是節(jié)選自etcd項目etcd/server/embed/config_logging.go中的部分代碼,代表的是err鏈中有沒有能當(dāng)做json.SyntaxError類型的錯誤的,如果能,則將err中的錯誤值賦值到syntaxError變量上,代碼如下:

// setupLogRotation initializes log rotation for a single file path target.
func setupLogRotation(logOutputs []string, logRotateConfigJSON string) error {
	//...

	if err := json.Unmarshal([]byte(logRotateConfigJSON), &logRotationConfig); err != nil {
		var unmarshalTypeError *json.UnmarshalTypeError
		var syntaxError *json.SyntaxError
		switch {
		case errors.As(err, &syntaxError):
			return fmt.Errorf("improperly formatted log rotation config: %w", err)
		case errors.As(err, &unmarshalTypeError):
			return fmt.Errorf("invalid log rotation config: %w", err)
		}
	}
	zap.RegisterSink("rotate", func(u *url.URL) (zap.Sink, error) {
		logRotationConfig.Filename = u.Path[1:]
		return &logRotationConfig, nil
	})
	return nil
}

總結(jié)

本文從應(yīng)用場景的角度講解了各種創(chuàng)建錯誤方式的實際應(yīng)用場景。示例中的代碼盡量的選自golang源碼或開源項目。同時,每種的應(yīng)用場景并非絕對的,需要靈活應(yīng)用。希望本文對大家在實際使用中能夠有所幫助。

責(zé)任編輯:武曉燕 來源: Go學(xué)堂
相關(guān)推薦

2021-09-08 22:38:56

區(qū)塊鏈公有鏈網(wǎng)絡(luò)

2018-10-06 21:51:37

代碼SOLID編程

2023-04-28 07:49:13

Javawaitsleep

2022-01-05 16:16:02

查詢編程工程師

2018-08-28 16:10:36

2024-01-25 10:14:09

HashSetHashMapJava

2018-10-07 06:30:40

代碼設(shè)計模式面向?qū)ο笤瓌t

2021-11-26 08:07:16

MySQL SQL 語句數(shù)據(jù)庫

2021-03-24 08:44:11

代碼內(nèi)存消耗語言

2021-06-09 10:10:20

代碼內(nèi)存編程語言

2022-07-06 11:47:27

JAVAfor循環(huán)

2023-12-08 08:29:53

SpringAOP日志

2025-01-03 08:09:15

2020-12-21 14:42:42

大數(shù)據(jù)云計算人工智能

2024-10-16 17:10:41

2022-11-28 11:45:30

Go應(yīng)用場景

2014-04-17 16:42:03

DevOps

2022-07-26 00:00:22

HTAP系統(tǒng)數(shù)據(jù)庫

2018-12-21 11:24:55

Java時間處理編程語言

2020-12-31 05:49:44

FlinkSQL函數(shù)
點贊
收藏

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

国产精品对白一区二区三区| 欧美激情奇米色| 污网站免费在线| 很黄的网站在线观看| 国产不卡视频一区二区三区| 91av视频导航| 日本黄色录像视频| 日韩欧美在线精品| 欧美一区二区三区视频在线观看| 欧美网站免费观看| www.在线视频| 92国产精品观看| 91精品久久久久久久久久久| 五月天婷婷丁香| 色135综合网| 日韩电影免费观看中文字幕| 制服丝袜中文字幕第一页| 超碰在线公开| 亚洲欧洲国产日韩| 蜜桃狠狠色伊人亚洲综合网站| 国产精品久久婷婷| 蜜桃av综合| 久久人人爽人人爽人人片av高清| 国产调教在线观看| 日韩mv欧美mv国产网站| 欧美一级精品在线| 中文字幕第36页| 超碰高清在线| 亚洲综合色区另类av| 亚洲视频导航| 高h视频在线| 99久久er热在这里只有精品15| 91在线视频免费| 成人免费视频国产免费| 在线亚洲观看| 久久久久久有精品国产| 亚洲精品一区二区三区在线播放| 亚洲v天堂v手机在线| 亚洲风情亚aⅴ在线发布| www.午夜av| 国产精品天堂蜜av在线播放 | 亚洲av无一区二区三区| 无码日韩精品一区二区免费| 精品国产一区二区三区久久影院| 国内自拍第二页| 欧美aaa级| 欧美三级视频在线观看| 午夜视频你懂的| 国产一区一一区高清不卡| 欧美视频13p| 91国偷自产一区二区开放时间| 亚洲免费久久| av电影在线播放高清免费观看| 久久综合999| 久热国产精品视频一区二区三区| 人妻无码中文字幕| 播五月开心婷婷综合| 国产精品久久久久久久久久久久冷| 国产免费无遮挡| 国模一区二区三区白浆| 成人在线精品视频| 国产剧情久久久| 国产福利91精品| 成人欧美一区二区三区视频| 蜜臀av在线观看| 成人免费看视频| 国产一区不卡在线观看| av女名字大全列表| 国产视频一区在线观看| 欧美日韩在线高清| 亚洲免费视频一区二区三区| 亚洲色图19p| 黄色一级片黄色| 韩日毛片在线观看| 日韩欧美在线看| 欧美日韩怡红院| 四虎国产精品永久在线国在线| 欧美一级黄色录像| 插我舔内射18免费视频| 蜜臀91精品国产高清在线观看| 国产亚洲精品综合一区91| 国产99在线 | 亚洲| 亚洲蜜桃视频| 91精品国产高清久久久久久久久 | 欧美日韩午夜视频在线观看| 欧美精品色婷婷五月综合| 日韩欧美精品一区二区综合视频| 欧美日韩一卡二卡| 国产精品无码自拍| 一区二区三区视频免费观看| 精品国产自在精品国产浪潮 | 日韩欧美国产黄色| 狠狠干狠狠操视频| 草草视频在线一区二区| 亚洲一级黄色片| 欧产日产国产v| 久久国产精品毛片| 国产极品精品在线观看| 国产一区二区三区黄片| 9人人澡人人爽人人精品| 午夜精品福利一区二区| 久草在线新免费首页资源站| 一本色道亚洲精品aⅴ| 中文字幕第22页| 精品一区在线| 欧美高清videos高潮hd| 无码人妻精品一区二区50| 激情都市一区二区| 久久久久久久久久久久久久一区| a在线免费观看| 欧美性受极品xxxx喷水| 91超薄肉色丝袜交足高跟凉鞋| av中字幕久久| 欧美亚洲国产日本| 精品美女www爽爽爽视频| 久久精品人人做人人爽人人| 成人免费毛片在线观看| 亚洲免费一区| 亚洲乱码av中文一区二区| 欧美日韩综合一区二区| 美女视频黄 久久| 久久精品日产第一区二区三区乱码 | 99热这里只有精品4| 免费看亚洲片| 国产欧美精品一区二区三区| www在线视频| 欧美视频精品在线| 37p粉嫩大胆色噜噜噜| 亚洲午夜伦理| 91精品国产综合久久久久久丝袜| 高清毛片在线看| 一本色道a无线码一区v| 欧美xxxxx精品| 中文字幕一区二区av | 九九99久久精品在免费线bt| 亚洲天堂视频在线观看| 亚洲精品视频在线观看免费视频| 国产精品一区二区在线看| 午夜一区二区三视频在线观看| 涩涩视频在线免费看| 亚洲成色777777女色窝| 精品在线视频免费| 国产成人欧美日韩在线电影| gogogo免费高清日本写真| 男人天堂久久| 正在播放亚洲1区| 一级黄色在线观看| 欧美极品少妇xxxxⅹ高跟鞋 | 欧美大胆性生话| 精品爽片免费看久久| 国产小视频在线免费观看| 成人av在线观| 国模无码视频一区二区三区| 日韩av影院| 欧美亚洲成人xxx| 欧美日韩在线中文字幕| 精品日本美女福利在线观看| 亚洲av网址在线| 国产欧美日本| 蜜桃欧美视频| 国产精品亚洲一区二区三区在线观看 | 一区二区三区中文在线观看| 精品人妻一区二区乱码| 欧美三区美女| 蜜桃视频成人| 秋霞国产精品| 日韩中文字幕视频| 国产丝袜在线视频| 亚洲激情av在线| 99热超碰在线| 久久不射网站| 亚洲精品成人三区| 国产一区 二区| 欧美激情在线视频二区| 神马久久久久久久久久| 亚洲成人动漫av| 黄色在线观看av| 日韩成人精品在线| 少妇高潮大叫好爽喷水| 国产一区丝袜| 国产成人亚洲综合91精品| 在线日本视频| 欧美大片一区二区三区| 国产精品suv一区二区三区| 国产亚洲精品bt天堂精选| 日本黄色的视频| 亚洲国产黄色| 台湾成人av| 99亚洲乱人伦aⅴ精品| 欧美制服第一页| 欧美69xxxx| 精品sm在线观看| 无码人妻精品一区二| 亚洲欧洲日韩av| 国产伦精品一区二区免费| 日韩专区一卡二卡| 日本大片免费看| 精品日本12videosex| 亚洲在线观看视频| 成人香蕉视频| 九九久久综合网站| 久草福利在线| 精品免费视频一区二区| 夜夜躁日日躁狠狠久久av| 亚洲资源中文字幕| 精品人妻中文无码av在线| 国产成人午夜精品影院观看视频 | av黄色在线看| 日韩一区日韩二区| 国精品无码人妻一区二区三区| 精品一区二区久久| 乱子伦视频在线看| 国内一区二区三区| 咪咪色在线视频| 亚洲亚洲免费| 国产福利久久精品| 在线播放成人| 国产福利视频一区二区| av影视在线| 久久色在线播放| 激情在线视频| 亚洲精品国产品国语在线| 国产又粗又猛又黄又爽| 欧美性受xxxx黑人xyx| 久久久久女人精品毛片九一| 亚洲无人区一区| 小泽玛利亚一区| 国产欧美中文在线| 黄色国产在线观看| 成人黄色大片在线观看 | 波多野结衣在线观看视频| 亚洲第一激情av| 妺妺窝人体色www婷婷| 国产精品二三区| 337人体粉嫩噜噜噜| 久久综合九色欧美综合狠狠| jjzz黄色片| 国产精品一区二区久久精品爱涩 | 国产a精品视频| 亚洲黄色av片| 麻豆精品视频在线| 浓精h攵女乱爱av| 丝袜a∨在线一区二区三区不卡| 97成人在线免费视频| 欧美色综合网| 国产中文字幕乱人伦在线观看| 欧美大片专区| 欧美三级午夜理伦三级老人| 欧美aaaa视频| 最新av在线免费观看| 91精品国产乱码久久久久久| 亚洲最大色综合成人av| 久久电影院7| 一区二区在线观| 欧美成人自拍| 亚洲第一页在线视频| 99国产**精品****| 在线视频不卡国产| 中文字幕亚洲综合久久五月天色无吗'' | 午夜视频免费看| 精品香蕉一区二区三区| 美女毛片在线看| 一本色道久久综合亚洲精品小说 | 欧美大片在线看| 免费在线国产视频| 午夜精品视频在线| 免费在线小视频| 国产精品1234| www.久久久.com| yellow视频在线观看一区二区 | 日韩欧美电影一二三| 亚洲精品一区二区三区新线路| 精品国产乱码久久久久久影片| 天天干天天操av| 在线日韩欧美视频| 搞黄网站在线观看| 97色伦亚洲国产| **在线精品| 成人免费黄色网| 在这里有精品| 欧美日韩在线一区二区三区| 久久人人88| 青春草国产视频| 日韩av在线发布| 久热精品在线播放| 成人一区二区三区视频在线观看| 你懂得在线视频| 1024成人网| 午夜影院在线看| 欧美挠脚心视频网站| 蜜桃在线一区二区| 中文字幕亚洲二区| 白白色在线观看| 国产精品精品视频一区二区三区| avtt久久| 欧美日韩国产不卡在线看| 久久日文中文字幕乱码| 日本韩国欧美在线观看| 精品中文字幕一区二区小辣椒| 久久精品无码专区| 国产精品久久久久9999吃药| 国产精品第一页在线观看| 欧美视频一二三区| 天堂国产一区二区三区| 日韩中文字在线| 色是在线视频| av资源一区二区| 色欧美自拍视频| 少妇高潮喷水久久久久久久久久| 麻豆成人av在线| 好吊视频在线观看| 亚洲尤物视频在线| 一级成人免费视频| 精品视频中文字幕| 欧美xxxx免费虐| 91久久久久久久久久久久久| 啄木系列成人av电影| 日本一本中文字幕| 国产在线精品免费| 精品日韩在线视频| 欧美视频一二三| 日韩一级中文字幕| 欧美成人免费网| gogo大尺度成人免费视频| 日本在线观看一区二区| 亚洲影院一区| 一边摸一边做爽的视频17国产| 中文字幕一区二区三区在线观看 | 成人一级福利| 97人人做人人人难人人做| 欧美高清视频手机在在线| 狠狠爱免费视频| 不卡的看片网站| 国产亚洲精品久久久久久无几年桃| 欧美三级电影精品| 国产精品免费观看| 欧美有码在线视频| 亚洲第一福利社区| 日本三级免费观看| 久久免费午夜影院| 国产成人在线免费视频| 亚洲国产欧美一区| 丁香花在线影院| 国产一区二区精品在线| 极品av少妇一区二区| 国产婷婷在线观看| 亚洲国产精品嫩草影院| 蜜桃av噜噜一区二区三区麻豆| 九九精品在线观看| 成人午夜网址| 亚洲一区二区三区av无码| 成人激情午夜影院| 激情综合网五月婷婷| 亚洲大胆人体av| 国产免费拔擦拔擦8x在线播放| 久久av一区二区三区亚洲| 亚洲免费大片| 久久久久久久久久久国产精品| 色网站国产精品| 成年人在线观看视频| 国产在线拍偷自揄拍精品| 婷婷亚洲最大| 佐山爱在线视频| 亚洲成人自拍一区| 少妇性bbb搡bbb爽爽爽欧美| 日韩美女激情视频| 日韩专区精品| 一卡二卡三卡四卡五卡| 亚洲大片在线观看| 日韩福利一区二区| 国产视频福利一区| 欧美日韩精品免费观看视频完整| 91精品又粗又猛又爽| 欧美性xxxxxxx| 一区二区三区视频在线观看视频| 91日本在线观看| 韩国一区二区三区在线观看| 在线免费播放av| 欧美三级电影在线观看| 在线中文字幕视频观看| 九九99久久| 久久99热这里只有精品| 国产在线视频卡一卡二| 亚洲人成网站免费播放| 成人51免费| 亚欧无线一线二线三线区别| 国产精品久久久久一区| 亚洲精品成人电影| 国产成人精品一区二区| 欧美在线不卡| 蜜桃传媒一区二区亚洲av| 91精品免费观看| 亚洲精品福利电影| 自拍视频一区二区三区| 成人激情免费电影网址| 日韩不卡高清视频| 欧美精品精品精品精品免费| 国产成人ay| 东京热av一区| 欧美日韩国产另类不卡|