go經典語言錯誤 go語言異常處理

go語言語法(基礎語法篇)

import "workname/packetfolder"

廣平網站建設公司成都創(chuàng)新互聯,廣平網站設計制作,有大型網站制作公司豐富經驗。已為廣平成百上千提供企業(yè)網站建設服務。企業(yè)網站搭建\外貿營銷網站建設要多少錢,請找那個售后服務好的廣平做網站的公司定做!

導入多個包

方法調用 包名.函數//不是函數或結構體所處文件或文件夾名

packagename.Func()

前面加個點表示省略調用,那么調用該模塊里面的函數,可以不用寫模塊名稱了:

當導入一個包時,該包下的文件里所有init()函數都會被執(zhí)行,然而,有些時候我們并不需要把整個包都導入進來,僅僅是是希望它執(zhí)行init()函數而已。下劃線的作用僅僅是為了調用init()函數,所以無法通過包名來調用包中的其他函數

import _ package

變量聲明必須要使用否則會報錯。

全局變量運行聲明但不使用。

func 函數名 (參數1,參數2,...) (返回值a 類型a, 返回值b 類型b,...)

func 函數名 (參數1,參數2,...) (返回值類型1, 返回值類型2,...)

func (this *結構體名) 函數名(參數 string) (返回值類型1, 返回值類型2){}

使用大小來區(qū)分函數可見性

大寫是public類型

小寫是private類型

func prifunc int{}

func pubfunc int{}

聲明靜態(tài)變量

const value int

定義變量

var value int

聲明一般類型、接口和結構體

聲明函數

func function () int{}

go里面所有的空值對應如下

通道類型

內建函數 new 用來分配內存,它的第一個參數是一個類型,不是一個值,它的返回值是一個指向新分配類型零值的指針

func new(Type) *Type

[這位博主有非常詳細的分析]

Go 語言支持并發(fā),我們只需要通過 go 關鍵字來開啟 goroutine 即可。

goroutine 是輕量級線程,goroutine 的調度是由 Golang 運行時進行管理的。

同一個程序中的所有 goroutine 共享同一個地址空間。

語法格式如下:

通道(channel)是用來傳遞數據的一個數據結構。

通道的聲明

通道可用于兩個 goroutine 之間通過傳遞一個指定類型的值來同步運行和通訊。操作符 - 用于指定通道的方向,發(fā)送或接收。如果未指定方向,則為雙向通道。

[這里有比較詳細的用例]

go里面的空接口可以指代任何類型(無論是變量還是函數)

聲明空接口

go里面的的強制類型轉換語法為:

int(data)

如果是接口類型的強制轉成其他類型的語法為:

go里面的強制轉換是將值復制過去,所以在數據量的時候有比較高的運行代價

深入剖析:一套在 Go 中傳遞、返回、暴露錯誤,便于回查的解決方案

作者:andruzhang,騰訊 IEG 后臺開發(fā)工程師

在后臺開發(fā)中,針對錯誤處理,有三個維度的問題需要解決:

一個面向過程的函數,在不同的處理過程中需要 handle 不同的錯誤信息;一個面向對象的函數,針對一個操作所返回的不同類型的錯誤,有可能需要進行不同的處理。此外,在遇到錯誤時,也可以使用斷言的方式,快速中止函數流程,大大提高代碼的可讀性。

在許多高級語言中都提供了 try ... catch 的語法,函數內部可以通過這種方案,實現一個統(tǒng)一的錯誤處理邏輯。而即便是 C 這種 “中級語言” 雖然沒有,但是程序員也可以使用宏定義的方式,來實現某種程度上的錯誤斷言。

但是,對于 Go 的情況就比較尷尬了。

我們先來看斷言,我們的目的是,僅使用一行代碼就能夠檢查錯誤并終止當前函數。由于沒有 throw,沒有宏,如果要實現一行斷言,有兩種方法。

第一種是把 if 的錯誤判斷寫在一行內,比如:

第二種方法是借用 panic 函數,結合 recover 來實現:

這兩種方法都值得商榷。

首先,將 if 寫在同一行內的問題有:

至于第二種方法,我們要分情況看;

不過使用 panic 來斷言的方案,雖然在業(yè)務邏輯中基本上不用,但在測試場景下則是非常常見的。測試嘛,用牛刀有何不可?稍微大一點的系統(tǒng)開銷也沒啥問題。對于 Go 來說,非常熱門的單元測試框架 goconvey 就是使用 panic 機制來實現單元測試中的斷言,用的人都說好。

綜上,在 Go 中,對于業(yè)務代碼,筆者不建議采用斷言,遇到錯誤的時候建議還是老老實實采用這種格式:

而在單測代碼中,則完全可以大大方方地采用類似于 goconvey 之類基于 panic 機制的斷言。

眾所周知 Go 是沒有 try ... catch 的,而且從官方的態(tài)度來看,短時間內也沒有考慮的計劃。但程序員有這個需求呀。筆者采用的方法,是將需要返回的 err 變量在函數內部全局化,然后結合 defer 統(tǒng)一處理:

這種方案要特別注意變量作用域問題.比如前面的 if err = DoSomething(); err != nil { 行,如果我們將 err = ... 改為 err := ...,那么這一行中的 err 變量和函數最前面定義的 (err error) 不是同一個變量,因此即便在此處發(fā)生了錯誤,但是在 defer 函數中無法捕獲到 err 變量了。

在 try ... catch 方面,筆者其實沒有特別好的方法來模擬,即便是上面的方法也有一個很讓人頭疼的問題:defer 寫法導致錯誤處理前置,而正常邏輯后置了,從可讀性的角度來說非常不友好。因此也希望讀者能夠指教。同時還是希望 Go 官方能夠繼續(xù)迭代,支持這種語法。

這一點在 Go 里面,一開始看起來還是比較統(tǒng)一的,這就是 Go 最開始就定義的 error 類型,以系統(tǒng)標準的方式,統(tǒng)一了進程內函數級的錯誤返回模式。調用方使用 if err != nil 的統(tǒng)一模式,來判斷一個調用是不是成功了。

但是隨著 Go 的逐步推廣,由于 error 接口的高自由度,程序員們對于 “如何判斷該錯誤是什么錯誤” 的時候,出現了分歧。

在 Go 1.13 之前,對于 error 類型的傳遞,有三種常見的模式:

這個流派很簡單,就是將各種錯誤信息直接定義為一個類枚舉值的模式,比如:

當遇到相應的錯誤信息時,直接返回對應的 error 類枚舉值就行了。對于調用方也非常方便,可以采用 switch - case 來判斷錯誤類型:

個人覺得這種設計模式本質上還是 C error code 模式。

這種流派則是充分使用了 “error 是一個 interface” 的特性,重新自定義一個 error 類型。一方面是用不同的類型來表示不同的錯誤分類,另一方面則能夠實現對于同一錯誤類型,能夠給調用方提供更佳詳盡的信息。舉個例子,我們可以定義多個不同的錯誤類型如下:

對于調用方,則通過以下代碼來判斷不同的錯誤:

這種模式,一方面可以透傳底層錯誤,另一方面又可以添加自定義的信息。但對于調用方而言,災難在于如果要判斷某一個錯誤的具體類型,只能用 strings.Contains() 來實現,而錯誤的具體描述文字是不可靠的,同一類型的信息可能會有不同的表達;而在 fmt.Errorf 的過程中,各個業(yè)務添加的額外信息也可能會有不同的文字,這帶來了極大的不可靠性,提高了模塊之間的耦合度。

在 go 1.13 版本發(fā)布之后,針對 fmt.Errorf 增加了 wraping 功能,并在 errors 包中添加了 Is() 和 As() 函數。關于這個模式的原理和使用已經有很多文章了,本文就不再贅述。

這個功能,合并并改造了前文的所謂 “== 流派” 和 “fmt.Errorf” 流派,統(tǒng)一使用 errors.Is() 函數;此外,也算是官方對類型斷言流派的認可(專門用 As() 函數來支持)。

在實際應用中,函數/模塊透傳錯誤時,應該采用 Go 的 error wrapping 模式,也就是 fmt.Errorf() 配合 %w 使用,業(yè)務方可以放心地添加自己的錯誤信息,只要調用方統(tǒng)一采用 errors.Is() 和 errors.As() 即可。

服務/系統(tǒng)層面的錯誤信息返回,大部分協議都可以看成是 code - message 模式或者是其變體:

這種模式的特點是:code 是給程序代碼使用的,代碼判斷這是一個什么類型的錯誤,進入相應的分支處理;而 message 是給人看的,程序可以以某種形式拋出或者記錄這個錯誤信息,供用戶查看。

在這一層面有什么問題呢?code for computer,message for user,好像挺好的。

但有時候,我們可能會收到用戶/客戶反饋一個問題:“XXX 報錯了,幫忙看看什么問題?”。用戶看不懂我們的錯誤提示嗎?

在筆者的經驗中,我們在使用 code - message 機制的時候,特別是業(yè)務初期,難以避免的是前后端的設計文案沒能完整地覆蓋所有的錯誤用例,或者是錯誤極其罕見。因此當出現錯誤時,提示曖昧不清(甚至是直接提示錯誤信息),導致用戶從錯誤信息中找到解決方案

在這種情況下,盡量覆蓋所有錯誤路徑肯定是最完美的方法。不過在做到這一點之前,碼農們往往有下面的解決方案:

既要隱藏信息,又要暴露信息,我可以摔盤子嗎……

這里,筆者從日益普及的短信驗證碼有了個靈感——人的短期記憶對 4 個字符還是比較強的,因此我們可以考慮把錯誤代碼縮短到 4 個字符——不區(qū)分大小寫,因為如果人在記憶時還要記錄大小寫的話,難度會增加不少。

怎么用 4 個字符表示盡量多的數據呢?數字+字母總共有 36 個字符,理論上使用 4 位 36 進制可以表示 36x36x36x36 = 1679616 個值。因此我們只要找到一個針對錯誤信息字符串的哈希算法,把輸出值限制在 1679616 范圍內就行了。

這里我采用的是 MD5 作為例子。MD5 的輸出是 128 位,理論上我可以取 MD5 的輸出,模 1679616 就可以得到一個簡易的結果。實際上為了減少除法運算,我采用的是取高 20 位(0xFFFFF)的簡易方式(20 位二進制的最大值為 1048575),然后將這個數字轉成 36 進制的字符串輸出。

當出現異常錯誤時,我們可以將 message 的提示信息如下展示:“未知錯誤,錯誤代碼 30EV,如需協助,請聯系 XXX”。順帶一提,30EV 是 "Access denied for user 'db_user'@'127.0.0.1'" 的計算結果,這樣一來,我就對調用方隱藏了敏感信息。

至于后臺側,還是需要實實在在地將這個哈希值和具體的錯誤信息記錄在日志或者其他支持搜索的渠道里。當用戶提供該代碼時,可以快速定位。

這種方案的優(yōu)點很明顯:

簡易的錯誤碼生成代碼如下:

當然這種方案也有局限性,筆者能想到的是需要注意以下兩點:

此外,筆者需要再強調的是:在開發(fā)中,針對各種不同的、正式的錯誤用例依然需要完整覆蓋,盡可能通過已有的 code - message 機制將足夠清晰的信息告知主調方。這種 hashcode 的錯誤代碼生成方法,僅適用于錯誤用例遺漏、或者是快速迭代過程中,用于發(fā)現和調試遺漏的錯誤用例的臨時方案。

go語言 一個主package包引入同級目錄下go文件包編譯出錯??!

go語言 一個主package包引入同級目錄下go文件包編譯出錯是設置錯誤造成的,解決方法為:

1、先使用import "strings"導入strings庫。

2、HasPrefix?判斷字符串?s?是否以?prefix?開頭。

3、HasSuffix?判斷字符串?s?是否以?suffix?結尾。

4、可以看看判斷的代碼。

5、在cmd下運行一下go run test.go,看看如下結果。

6、Contains?判斷字符串?s?是否包含?substr,也就是判斷一下S是否在strings中。

7、在cmd下運行go run test.go看看結果。

Go 語言的錯誤處理機制是一個優(yōu)秀的設計嗎

這個問題說來話長,我先表達一下我的觀點,Go語言從語法層面提供區(qū)分錯誤和異常的機制是很好的做法,比自己用單個返回值做值判斷要方便很多。

上面看到很多知乎大牛把異常和錯誤混在一起說,有認為Go沒有異常機制的,有認為Go純粹只有異常機制的,我覺得這些觀點都太片面了。

具體對于錯誤和異常的討論,我轉發(fā)一下前陣子寫的一篇日志拋磚引玉吧。

============================

最近連續(xù)遇到朋友問我項目里錯誤和異常管理的事情,之前也多次跟團隊強調過錯誤和異常管理的一些概念,所以趁今天有動力就趕緊寫一篇Go語言項目錯誤和異常管理的經驗分享。

首先我們要理清:什么是錯誤、什么是異常、為什么需要管理。然后才是怎樣管理。

錯誤和異常從語言機制上面講,就是error和panic的區(qū)別,放到別的語言也一樣,別的語言沒有error類型,但是有錯誤碼之類的,沒有panic,但是有throw之類的。

在語言層面它們是兩種概念,導致的是兩種不同的結果。如果程序遇到錯誤不處理,那么可能進一步的產生業(yè)務上的錯誤,比如給用戶多扣錢了,或者進一步產生了異常;如果程序遇到異常不處理,那么結果就是進程異常退出。

在項目里面是不是應該處理所有的錯誤情況和捕捉所有的異常呢?我只能說,你可以這么做,但是估計效果不會太好。我的理由是:

如果所有東西都處理和記錄,那么重要信息可能被淹沒在信息的海洋里。

不應該處理的錯誤被處理了,很容易導出BUG暴露不出來,直到出現更嚴重錯誤的時候才暴露出問題,到時候排查就很困難了,因為已經不是錯誤的第一現場。

所以錯誤和異常最好能按一定的規(guī)則進行分類和管理,在第一時間能暴露錯誤和還原現場。

對于錯誤處理,Erlang有一個很好的概念叫速錯,就是有錯誤第一時間暴露它。我們的項目從Erlang到Go一直是沿用這一設計原則。但是應用這個原則的前提是先得區(qū)分錯誤和異常這兩個概念。

錯誤和異常上面已經提到了,從語言機制層面比較容易區(qū)分它們,但是語言取決于人為,什么情況下用錯誤表達,什么情況下用異常表達,就得有一套規(guī)則,否則很容易出現全部靠異常來做錯誤處理的情況,似乎Java項目特別容易出現這樣的設計。

這里我先假想有這樣一個業(yè)務:游戲玩家通過購買按鈕,用銅錢購買寶石。

在實現這個業(yè)務的時候,程序邏輯會進一步分化成客戶端邏輯和服務端邏輯,客戶端邏輯又進一步因為設計方式的不同分化成兩種結構:胖客戶端結構、瘦客戶端結構。

胖客戶端結構,有更多的本地數據和懂得更多的業(yè)務邏輯,所以在胖客戶端結構的應用中,以上的業(yè)務會實現成這樣:客戶端檢查緩存中的銅錢數量,銅錢數量足夠的時候購買按鈕為可用的亮起狀態(tài),用戶點擊購買按鈕后客戶端發(fā)送購買請求到服務端;服務端收到請求后校驗用戶的銅錢數量,如果銅錢數量不足就拋出異常,終止請求過程并斷開客戶端的連接,如果銅錢數量足夠就進一步完成寶石購買過程,這里不繼續(xù)描述正常過程。

因為正常的客戶端是有一步數據校驗的過程的,所以當服務端收到不合理的請求(銅錢不足以購買寶石)時,拋出異常比返回錯誤更為合理,因為這個請求只可能來自兩種客戶端:外掛或者有BUG的客戶端。如果不通過拋出異常來終止業(yè)務過程和斷開客戶端連接,那么程序的錯誤就很難被第一時間發(fā)現,攻擊行為也很難被發(fā)現。

我們再回頭看瘦客戶端結構的設計,瘦客戶端不會存有太多狀態(tài)數據和用戶數據也不清楚業(yè)務邏輯,所以客戶端的設計會是這樣:用戶點擊購買按鈕,客戶端發(fā)送購買請求;服務端收到請求后檢查銅錢數量,數量不足就返回數量不足的錯誤碼,數量足夠就繼續(xù)完成業(yè)務并返回成功信息;客戶端收到服務端的處理結果后,在界面上做出反映。

在這種結構下,銅錢不足就變成了業(yè)務邏輯范圍內的一種失敗情況,但不能提升為異常,否則銅錢不足的用戶一點購買按鈕都會出錯掉線。

所以,異常和錯誤在不同程序結構下是互相轉換的,我們沒辦法一句話的給所有類型所有結構的程序一個統(tǒng)一的異常和錯誤分類規(guī)則。

但是,異常和錯誤的分類是有跡可循的。比如上面提到的痩客戶端結構,銅錢不足是業(yè)務邏輯范圍內的一種失敗情況,它屬于業(yè)務錯誤,再比如程序邏輯上嘗試請求某個URL,最多三次,重試三次的過程中請求失敗是錯誤,重試到第三次,失敗就被提升為異常了。

所以我們可以這樣來歸類異常和錯誤:不會終止程序邏輯運行的歸類為錯誤,會終止程序邏輯運行的歸類為異常。

因為錯誤不會終止邏輯運行,所以錯誤是邏輯的一部分,比如上面提到的瘦客戶端結構,銅錢不足的錯誤就是業(yè)務邏輯處理過程中需要考慮和處理的一個邏輯分支。而異常就是那些不應該出現在業(yè)務邏輯中的東西,比如上面提到的胖客戶端結構,銅錢不足已經不是業(yè)務邏輯需要考慮的一部分了,所以它應該是一個異常。

錯誤和異常的分類需要通過一定的思維訓練來強化分類能力,就類似于面向對象的設計方式一樣的,技術實現就擺在那邊,但是要用好需要不斷的思維訓練不斷的歸類和總結,以上提到的歸類方式希望可以作為一個參考,期待大家能發(fā)現更多更有效的歸類方式。

接下來我們講一下速錯和Go語言里面怎么做到速錯。

速錯我最早接觸是在做的時候就體驗到的,當然跟Erlang的速錯不完全一致,那時候也沒有那么高大上的一個名字,但是對待異常的理念是一樣的。

在.NET項目開發(fā)的時候,有經驗的程序員都應該知道,不能隨便re-throw,就是catch錯誤再拋出,原因是異常的第一現場會被破壞,堆棧跟蹤信息會丟失,因為外部最后拿到異常的堆棧跟蹤信息,是最后那次throw的異常的堆棧跟蹤信息;其次,不能隨便try catch,隨便catch很容易導出異常暴露不出來,升級為更嚴重的業(yè)務漏洞。

到了Erlang時期,大家學到了速錯概念,簡單來講就是:讓它掛。只有掛了你才會第一時間知道錯誤,但是Erlang的掛,只是Erlang進程的異常退出,不會導致整個Erlang節(jié)點退出,所以它掛的影響層面比較低。

在Go語言項目中,雖然有類似Erlang進程的Goroutine,但是Goroutine如果panic了,并且沒有recover,那么整個Go進程就會異常退出。所以我們在Go語言項目中要應用速錯的設計理念,就要對Goroutine做一定的管理。

在我們的游戲服務端項目中,我把Goroutine按掛掉后的結果分為兩類:1、掛掉后不影響其他業(yè)務或功能的;2、掛掉后業(yè)務就無法正常進行的。

第一類Goroutine典型的有:處理各個玩家請求的Goroutine,因為每個玩家連接各自有一個Goroutine,所以掛掉了只會影響單個玩家,不會影響整體業(yè)務進行。

第二類Goroutine典型的有:數據庫同步用的Goroutine,如果它掛了,數據就無法同步到數據庫,游戲如果繼續(xù)運行下去只會導致數據回檔,還不如讓整個游戲都異常退出。

這樣一分類,就可以比較清楚哪些Goroutine該做recover處理,哪些不該做recover處理了。

那么在做recover處理時,要怎樣才能盡量保留第一現場來幫組開發(fā)者排查問題原因呢?我們項目中通常是會在最外層的recover中把錯誤和堆棧跟蹤信息記進日志,同時把關鍵的業(yè)務信息,比如:用戶ID、來源IP、請求數據等也一起記錄進去。

為此,我們還特地設計了一個庫,用來格式化輸出堆棧跟蹤信息和對象信息,項目地址:funny/debug · GitHub

通篇寫下來發(fā)現比我預期的長很多,所以這里我做一下歸納總結,幫組大家理解這篇文章所要表達的:

錯誤和異常需要分類和管理,不能一概而論

錯誤和異常的分類可以以是否終止業(yè)務過程作為標準

錯誤是業(yè)務過程的一部分,異常不是

不要隨便捕獲異常,更不要隨便捕獲再重新拋出異常

Go語言項目需要把Goroutine分為兩類,區(qū)別處理異常

在捕獲到異常時,需要盡可能的保留第一現場的關鍵數據

以上僅為一家之言,拋磚引玉,希望對大家有所幫助。

go語言unresolved type string

這是引入類型失敗的錯誤提示,

import org.wltea ,說明你引入了某個jar 包或者類,但是沒有找到 ,就報錯了.IK analyzer 中文分詞器 開源的項目 ,有源碼的.把這個下載好就可以了。

go語言中數組使用的注意事項和細節(jié)

1、數組是多個 相同類型 的數據的組合,一個數組一旦聲明/定義了,其 長度是固定的,不能動態(tài)變化 。

2、var arr []int? ? 這時arr就是一個slice 切片 。

3、數組中的元素可以是任何數據類型,包括值類型和引用類型,但是 不能混用 。

4、數組創(chuàng)建后,如果沒有賦值,有默認值如下:

? ? 數值類型數組:????默認值為 0

? ? 字符串數組:? ? ? ?默認值為 ""

? ? bool數組:? ? ? ? ? ?默認值為 false

5、使用數組的步驟:

? ? (1)聲明數組并開辟空間

? ? (3)給數組各個元素賦值

? ? (3)使用數組

6、數組的下標是從0開始的。

7、數組下標必須在指定范圍內使用,否則報panic:數組越界,比如var arr [5]int的有效下標為0~4.

8、Go的數組屬于 值類型 ,在默認情況下是 值傳遞 ,因此會進行值拷貝。 數組間不會相互影響。

9、如想在其他函數中去修改原來的數組,可以使用 引用傳遞 (指針方式)。

10、長度是數組類型的一部分,在傳遞函數參數時,需要考慮數組的長度,看以下案例:

題1:編譯錯誤,因為不能把[3]int類型傳遞給[]int類型,前者是數組,后者是切片;

題2:編譯錯誤,因為不能把[3]int類型傳遞給[4]int類型;

題3:編譯正確,因為[3]int類型傳給[3]int類型合法。

文章名稱:go經典語言錯誤 go語言異常處理
URL鏈接:http://m.kartarina.com/article8/hgjgop.html

成都網站建設公司_創(chuàng)新互聯,為您提供網站設計、建站公司網站導航、面包屑導航、企業(yè)網站制作、網站內鏈

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯

h5響應式網站建設
主站蜘蛛池模板: 无码毛片AAA在线| 国产高新无码在线观看| 无码 免费 国产在线观看91| AA区一区二区三无码精片| 亚洲精品GV天堂无码男同| 无码一区二区三区亚洲人妻| 中文字幕人妻无码系列第三区 | 亚洲AV无码AV男人的天堂| 无码人妻精品一区二区三区99性| 免费无码黄网站在线观看| 亚洲色无码专区在线观看| 免费无码AV电影在线观看| 无码精品久久久久久人妻中字| 日韩激情无码免费毛片| 未满十八18禁止免费无码网站| 亚洲AV无码成H人在线观看| 人妻精品久久无码专区精东影业| 亚洲人成无码www久久久| 精品久久久久久无码不卡| 国产精品无码AV一区二区三区| 免费无码看av的网站| 一本色道久久综合无码人妻| 无码人妻AV免费一区二区三区 | 办公室丝袜激情无码播放| 亚洲AV无码一区二区一二区| 亚洲av无码潮喷在线观看| 亚洲日韩欧洲无码av夜夜摸| 亚洲一本大道无码av天堂| 永久免费AV无码网站在线观看| 久久精品无码专区免费青青| 无码国产精品一区二区免费模式| 一本色道无码不卡在线观看| 久久久久无码专区亚洲av| 国产AV无码专区亚洲AV麻豆丫| 中文无码亚洲精品字幕| 亚洲a∨无码男人的天堂| 久久无码高潮喷水| 久久久国产精品无码免费专区| 国产亚洲精久久久久久无码| 亚洲av中文无码乱人伦在线咪咕| 国产精品免费无遮挡无码永久视频 |