久久精品国产精品国产精品污,男人扒开添女人下部免费视频,一级国产69式性姿势免费视频,夜鲁夜鲁很鲁在线视频 视频,欧美丰满少妇一区二区三区,国产偷国产偷亚洲高清人乐享,中文 在线 日韩 亚洲 欧美,熟妇人妻无乱码中文字幕真矢织江,一区二区三区人妻制服国产

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

第61篇 笔记-Go 基础

發布時間:2023/12/9 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第61篇 笔记-Go 基础 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

一、go原則

二、組織代碼項目

三、數據類型

四、fmt 格式

五、package 包

5.1 可見性與作用域

5.2 包的導入

六、函數

6.1 main()?函數

6.2 init() 初始化函數

6.3 自定義函數

6.4 更改函數參數值

七、控制語句

7.1 if 語句

7.2 switch 語句

7.3 select 語句

7.4 break?語句

7.5?continue 語句

7.6?goto 語句

7.7 defer 函數

7.8?panic 函數與 recover 函數

7.9 示例:用戶登錄(流程控制)

7.10 示例:錯誤處理(控制流中斷)

八、數組

8.1 聲明與初始化

8.2 賦值與訪問

8.3 range遍歷

九、切片

9.1 切片內部結構

9.2 切片項

9.3 append() 和 copy() 函數

9.4 容量cap變化規律

9.5 示例:斐波納契數列

十、映射

10.1 定義 Map

10.2 添加與刪除

10.3 判斷存在

十一、結構體

11.1?聲明和初始化

11.2?結構嵌入

11.3 JSON 序列化

十二、方法

12.1 聲明方法

12.2 方法的重載

12.3 方法的封裝

12.4 函數與方法的區別

十三、接口

13.1 示例:interface聲明與使用方法

13.2 示例:創建用于管理在線商店的程序包

13.3 示例:通過實現接口對結構體切片進行排序

十四、類型斷言

十五、隨機數

15.1 偽隨機示例:math/rand

15.2 真隨機示例:crypto/rand

十六、日期與時間

16.1 type Time

16.2 示例:日期與時間

16.3 type Duration

十七、cmd編譯

17.1 兩種編譯方法

17.2 go build命令

17.3 go build示例

17.4 go install命令

17.5 go install示例

十八、錯誤處理策略

18.1 示例

18.2 處理策略:

十九、日志記錄

19.1 log包

19.2 記錄到文件

二十、反射

二十一、nil


一、go原則

(1)Go 致力于使事情變得簡單,用更少的代碼行執行更多操作。

(2)并發是首選,函數可作為輕量線程運行。

(3)編譯和執行速度快,目標是與 C 一樣快。

(4)Go 要求強制轉換是顯式的,否則會引發編譯錯誤。

(5)未使用的代碼不是警告,而是錯誤,代碼將不會編譯。

(6)有一種官方格式設置,有助于保持項目之間的一致性。

(7)Go 并不適用于框架,因為它更傾向于使用標準庫。

(8)Go 確保向后兼容性。

(9)Go 許可證是完全開放源代碼。

?

二、組織代碼項目

Go 在組織項目文件方面與其他編程語言不同。 首先,Go 在工作區的概念之下工作,其中,工作區就是應用程序源代碼所在的位置。 在 Go 中,所有項目共享同一個工作區。 不過,從版本 1.11 開始,Go 開始更改此方法。? 現在,Go 工作區位于 $HOME/go,但如果需要,可以為所有項目設置其他位置。

若要定義其他工作區位置,請將值設置為 $GOPATH 環境變量。 開始創建更復雜的項目時,需要為環境變量設置一個值,以避免將來出現問題。

在 macOS 或 Linux 中,可以:

// 通過將以下命令添加到?~/.profile?來配置工作區: export GOPATH=$HOME/go// 然后運行以下命令以更新環境變量: source ~/.profile

在Windows 中,創建一個文件夾(例如?C:\Projects\Go),你將在其中創建所有 Go 項目。 打開 PowerShell 提示符,然后運行以下命令:

[Environment]::SetEnvironmentVariable("GOPATH", "C:\Projects\Go", "User")

在 Go 中,可以通過打印 $GOPATH 環境變量的值來獲取工作區位置,以供將來參考。 或者,可以通過運行以下命令獲取與 Go 相關的環境變量:

go env

在 Go 工作區中,可以找到以下文件夾:

  • bin:包含應用程序中的可執行文件。
  • src:包括位于工作站中的所有應用程序源代碼。
  • pkg:包含可用庫的已編譯版本。 編譯器可以鏈接這些庫,而無需重新編譯它們。

?

三、數據類型

Go 有四類數據類型:

  • 基本類型:數字、字符串和布爾值
  • 聚合類型:數組和結構
  • 引用類型:指針、切片、映射、函數和通道
  • 接口類型:接口
  • 值類型與引用類型用法的區別

  • 值類型包括基本類型聚合類型
  • 值類型內存中變量存儲的是具體的值,變量在內存中的地址可以通過 &num 來獲取;引用類型變量直接存放的就是一個地址值,這個地址值指向的空間存的才是值。
  • 值類型內存通常在棧中分配;引用類型變量存儲的地址(也就是通過指針訪問類型里面的數據),通常真正的值在堆上分配。
  • 函數引用時,作為參數的值類型不修改原始數據;引用類型修改數據內容。
  • 默認值:

    • int?類型的:?0(及其所有子類型,如?int64)
    • float32?和?float64?類型的:?+0.000000e+000
    • bool?類型的:?false
    • string?類型的:空值

    ?

    四、fmt 格式

    通用:%v 值的默認格式表示%+v 類似%v,但輸出結構體時會添加字段名%#v 值的Go語法表示%T 值的類型的Go語法表示%% 百分號布爾值:%t 單詞true或false整數:%b 表示為二進制%c 該值對應的unicode碼值%d 表示為十進制%o 表示為八進制%q 該值對應的單引號括起來的go語法字符字面值,必要時會采用安全的轉義表示%x 表示為十六進制,使用a-f%X 表示為十六進制,使用A-F%U 表示為Unicode格式:U+1234,等價于"U+%04X"浮點數與復數的兩個組分:%b 無小數部分、二進制指數的科學計數法,如-123456p-78;參見strconv.FormatFloat%e 科學計數法,如-1234.456e+78%E 科學計數法,如-1234.456E+78%f 有小數部分但無指數部分,如123.456%F 等價于%f%g 根據實際情況采用%e或%f格式(以獲得更簡潔、準確的輸出)%G 根據實際情況采用%E或%F格式(以獲得更簡潔、準確的輸出)字符串和[]byte%s 直接輸出字符串或者[]byte%q 該值對應的雙引號括起來的go語法字符串字面值,必要時會采用安全的轉義表示%x 每個字節用兩字符十六進制數表示(使用a-f)%X 每個字節用兩字符十六進制數表示(使用A-F) 指針:%p 表示為十六進制,并加上前導的0x 沒有%u。整數如果是無符號類型自然輸出也是無符號的。類似的,也沒有必要指定操作數的尺寸(int8,int64)。寬度與精度:%f: 默認寬度,默認精度%9f 寬度9,默認精度%.2f 默認寬度,精度2%9.2f 寬度9,精度2%9.f 寬度9,精度0

    ?

    五、package 包

    (1)包(package)是多個Go源碼的集合,go語言有很多內置包,比如fmt,os,io等;

    (2)一個文件夾下的所有源碼文件只能屬于同一個包,同樣屬于同一個包的源碼文件不能放在多個文件夾下;

    (3)包名一般是小寫的,使用一個簡短且有意義的名稱;

    (4)main包是一個可執行的包,是應用程序的入口包,編譯完會生成一個可執行文件;

    (5)編譯不包含 main 包的源碼文件時不會得到可執行文件;

    (6)包名一般要和所在的目錄同名,也可以不同,包名中不能包含 “-”等特殊符號;

    (7)包一般使用域名作為目錄名稱,這樣能保證包名的唯一性;

    (8)GitHub 項目的包一般會放到?GOPATH/src/github.com/userName/projectName?目錄下;

    (9)任何源代碼文件必須屬于某個包,同時源碼文件的第一行有效代碼必須是?package?語句,通過該語句聲明自己所在的包。

    ?

    5.1 可見性與作用域

    變量作用域的好處:

  • 可以在多個位置使用相同的變量名而不引起任何沖突;
  • 脫離作用域的變量將不再可見并且無法訪問
  • 幫助更好地閱讀代碼;
  • go的作用域通常隨著大括號{ }的出現而開啟和結束;
  • 雖然沒有使用大括號,但關鍵字 case 和 default 也都引入了新的作用域;
  • 在 for 語句、if 語句或 switch 語句所在行聲明的變量,作用域持續至該語句結束為止;
  • 聲明變量的位置決定了變量所處的作用域;
  • 如果想在一個包中引用另外一個包里的標識符(如變量、常量、類型、函數等)時,該標識符必須是對外可見的(public)。

    在Go語言中只需要將標識符的首字母大寫就可以。

    // 首字母小寫,外部包不可見,只能在當前包內使用 var num = 10//首字母大寫外部包可見,可在其他包中使用 const Name ?= "ares"// 首字母小寫,外部包不可見,只能在當前包內使用 type person struct {name string }type Student struct {Name ?string ? ? ? ? ? //可在包外訪問的方法class string ? ? ? ? ? //僅限包內訪問的字段 }type Payer interface {init() ? ? ? ? ? ? ? ? //僅限包內訪問的方法Pay() ? ? ? ? ? ? ? ? ?//可在包外訪問的方法 }// 首字母大寫,外部包可見,可在其他包中使用 func Add(x, y int) int {return x + y }func age() { ? ? ? ? ? ? ? // 首字母小寫,外部包不可見,只能在當前包內使用var Age = 18 ? ? ? ? ? // 函數局部變量,外部包不可見,只能在當前函數內使用fmt.Println(Age) }

    5.2 包的導入

    (1)使用import關鍵字;

    (2)import導入語句通常放在文件開頭包聲明語句的下面;

    (3)導入的包名需要使用雙引號包裹起來;

    (4)當你導入多個包時,導入的順序會按照字母排序;

    (5)導入包即等同于包含了這個包的所有的代碼對象;

    (6)導入的包必須要被使用,否則程序編譯時也會報錯。

    導入格式:

    Go包的引入格式常見的有四種,下面以引用"fmt"包為例說明:

    import "fmt" ? ? ? ? ? ? // 標準引用 import fmt_go "fmt" ? ? ?// 別名引用,fmt_go是引用fmt包的別名,此時使用fmt包的功能時需要用fmt_go.方法來使用 import . "fmt" ? ? ? ? ? // 省略方式,這種引用相當于把包fmt的命名空間合并到當前程序的命名空間了,因此可以直接引用,不用在加上前綴fmt. import _ "fmt" ? ? ? ? ? // 匿名引用,僅執行包的初始化函數,不使用包內數據

    導入路徑:

    import導入時,會從GO的安裝目錄(也就是GOROOT環境變量設置的目錄)和GOPATH環境變量設置的目錄中,檢索 src/package 來導入包。如果不存在,則導入失敗。

    • GOROOT,就是GO內置的包所在的位置;
    • GOPATH,就是我們自己定義的包的位置。

    關于我們自己定義的包的導入路徑有多種說法,本文進行了實際測試;

    假設文件結構:

    D:\golang\.|└──src├──add│ ? └───add.go└──main└───main.go└───sub└───sub.go

    包的引用策略:

    // 第一種情況 // 如果設置了 GOPATH = D:\golang // 包名默認是從 $GOPATH/src/ 后開始計算的 import ( ? ?"add""main/sub" )// 第二種情況 // 如果沒有設置 GOPATH = D:\golang // 只能使用相對路徑 import ( ? ?"../add" ? ? ? ? ? ? ? //上級目錄"./sub" ? ? ? ? ? ? ? ?//本級目錄往下 )

    特別注意:本文測試中,兩種方法與?GOPATH 的設置相對應;即:

    • 如果源碼在 GOPATH 目錄下,包的引用只能使用第一種方法,不能使用相對路徑(不知道這個是什么邏輯);
    • 如果源碼不在 GOPATH 目錄下,只能使用相對路徑,而不能使用第一種方法;
      ?

    六、函數

    6.1 main()?函數

    與之交互的函數是?main()?函數。 Go 中的所有可執行程序都具有此函數,因為它是程序的起點。

    你的程序中只能有一個?main()?函數。 如果創建的是 Go 包,則無需編寫?main()?函數。?

    main()?函數沒有任何參數,并且不返回任何內容。 但這并不意味著其不能從用戶讀取值,如命令行參數。

    6.2 init() 初始化函數

    在Go語言程序執行時導入包語句會自動觸發包內部init()函數的調用。需要注意的是: init()函數沒有參數也沒有返回值。

    import "fmt"var x = 100func init() {fmt.Println(x) //100 } func main() {fmt.Println("Hello!") //Hello! }

    包中init函數的執行時機:

    ? ? ? ? 全局聲明 ===> init() ====> main()

    init()函數執行順序:

    init()?函數與 main() 函數對比:

    (1)都是go語言中的保留函數。init()用于初始化信息,main()用于座位程序入口;

    (2)兩個函數定義的時候,不能有參數和返回值,只能由go程序自動調用,不能被引用;

    (3)init()函數可以定義在任意包中,可以有多個。main()函數只能在main包下,并且只能有一個;

    (4)存在依賴的包之間不能循環導入;

    (5)一個包可以被其他多個包import,但是只能被初始化一次。

    執行順序:

    • 先執行init()函數,后執行main()函數
    • 對于同一個go文件中,調用順序是從上向下的,也就是先寫的先被執行,后寫的后被執行
    • 對于同一個包下,將文件名稱按照字符串進行排序,之后順序調用哥哥文件中的init()函數
    • 不同包下,如果不存在依賴,按照main包中的import順序來調用對應包中的init()函數;如果存在依賴,最后被依賴 的最先被初始化,導入順序:main-->A-->B-->C,執行順序,C-->B-->A--main


    6.3 自定義函數

    下面是用于創建函數的語法:

    func name(parameters) (results) {body-content }
  • 使用?func?關鍵字來定義函數,然后為其指定名稱。
  • 在命名后,指定函數的參數列表。 你可以指定零個或多個參數。
  • 你還可以定義函數的返回類型,該函數也可以是零個或多個。只需在末尾添加?return?行。
  • 在 Go 中,函數可以返回多個值。 你可以采用類似于定義函數參數的方式來定義這些值。 換句話說,你可以指定一個類型和名稱,但該名稱是可選的。
  • 如果不需要函數的某個返回值,可以通過將返回值分配給?_?變量來放棄該函數。?_?變量是 Go 忽略返回值的慣用方式。 它允許程序進行編譯。?
  • 示例:

    func main() {sum, _ := calc(os.Args[1], os.Args[2]) // 放棄calc函數的第 2 個返回值println("Sum:", sum) }

    6.4 更改函數參數值

    將值傳遞給函數時,該函數中的每個更改都不會影響調用方。

    Go 是“按值傳遞”編程語言。 這意味著每次向函數傳遞值時,Go 都會使用該值并創建本地副本(內存中的新變量)。

    在函數中對該變量所做的更改都不會影響你向函數發送的更改。

    指針:

    如果你希望在?自定義?函數中進行的更改會影響?main?函數中的變量,則需要使用指針。?

    指針是包含另一個變量的內存地址的變量。 當你發送指向某個函數的指針時,不會傳遞值,而是傳遞地址內存。 因此,對該變量所做的每個更改都會影響調用方。

    在 Go 中,有兩個運算符可用于處理指針:

    • &?運算符使用其后對象的地址。
    • *?運算符取消引用指針。 也就是說,你可以前往指針中包含的地址訪問其中的對象。

    示例:

    package mainfunc main() {firstName := "John"updateName(&firstName)println(firstName) }func updateName(name *string) {*name = "David" }

    運行前面的代碼。 請注意,輸出現在顯示的是?David,而不是?John。

    首先要做的就是修改函數的參數,以指明你要接收指針。 為此,請將參數類型從?string?更改為?*string。(后者仍是字符串,但現在它是指向字符串的指針。)然后,將新值分配給該變量時,需要在該變量的左側添加星號 (*) 以暫停該變量的值。 調用?updateName?函數時,系統不會發送值,而是發送變量的內存地址。 這就是前面的代碼在變量左側帶有?&?符號的原因。

    ?

    七、控制語句

    7.1 if 語句

    (1)不需使用括號將條件包含起來;

    (2)大括號{}必須存在,即使只有一行語句;

    (3)左括號必須在if或else的同一行;

    (4)在if之后,條件語句之前,可以添加變量初始化語句,使用";"進行分隔;

    (5)在有返回值的函數中,最終的return不能在條件語句中。

    ?

    7.2 switch 語句

    (1)switch 語句用于基于不同條件執行不同動作,每一個 case 分支都是唯一的,從上至下逐一測試,直到匹配為止;

    (2)case 后的各個表達式的值的數據類型,必須和 switch 的表達式數據類型一致;

    (3)case 后的表達式如果是常量(字面量),則要求不能重復;

    (4)switch 語句執行的過程從上至下,直到找到匹配項,匹配項后面也不需要再加 break;

    (5)switch 默認情況下 case 最后自帶 break 語句,匹配成功后就不會執行其他 case,如果我們需要執行后面的 case,可以使用?fallthrough ;

    (6)switch 從第一個判斷表達式為 true 的 case 開始執行,如果 case 帶有 fallthrough,程序會繼續執行下一條 case,且它不會去判斷下一個 case 的表達式是否為 true。

    (7)switch 后面可以不帶表達式,類似 if-else 分支來使用;

    ?

    7.3 select 語句

    (1)每個 case 都必須是一個通信;

    (2)所有 channel 表達式都會被求值;

    (3)所有被發送的表達式都會被求值;

    (4)如果任意某個通信可以進行,它就執行,其他被忽略;

    (5)如果有多個 case 都可以運行,Select 會隨機公平地選出一個執行。其他不會執行;

    (6)如果有 default 子句,則執行該語句。如果沒有 default 子句,select 將阻塞,直到某個通信可以運行;Go 不會重新對 channel 或值進行求值。

    ?

    7.4 break?語句

    (1)用于循環語句中跳出循環,并開始執行循環之后的語句;

    (2)break 在 switch(開關語句)中在執行一條 case 后跳出語句的作用;

    (3)在多重循環中,可以用標號 label 標出想 break 的循環。

    ?

    7.5?continue 語句

    (1)有點像 break 語句。但是 continue 不是跳出循環,而是跳過當前循環執行下一次循環語句;

    (2)for 循環中,執行 continue 語句會觸發 for 增量語句的執行;

    (3)在多重循環中,可以用標號 label 標出想 continue 的循環。

    ?

    7.6?goto 語句

    (1)無條件地轉移到過程中指定的行。

    (2)goto 語句通常與條件語句配合使用。可用來實現條件轉移, 構成循環,跳出循環體等功能。

    (3)但是,在結構化程序設計中一般不主張使用 goto 語句, 以免造成程序流程的混亂,使理解和調試程序都產生困難。

    ?

    7.7 defer 函數

    (1)在 Go 中,defer?語句會推遲函數(包括任何參數)的運行,直到包含?defer?語句的函數完成。

    (2)通常情況下,當你想要避免忘記任務(例如關閉文件或運行清理進程)時,可以推遲某個函數的運行。

    (3)可以根據需要推遲任意多個函數。

    (4)defer 語句按逆序運行(后進先出),先運行最后一個,最后運行第一個。

    ?

    7.8?panic 函數與 recover 函數

    panic 函數:

    (1)運行時錯誤會使 Go 程序進入緊急狀態。 可以強制程序進入緊急狀態,但運行時錯誤(例如數組訪問超出范圍、取消對空指針的引用)也可能會導致進入緊急狀態。

    (2)內置?panic()?函數會停止正常的控制流。 所有推遲的函數調用都會正常運行。 進程會在堆棧中繼續,直到所有函數都返回。 然后,程序會崩潰并記錄日志消息。 此消息包含錯誤和堆棧跟蹤,有助于診斷問題的根本原因。

    (3)調用?panic()?函數時,可以添加任何值作為參數。 通常,你會發送一條錯誤消息,說明為什么會進入緊急狀態。

    recover 函數:

    (1)有時,你可能想要避免程序崩潰,改為在內部報告錯誤。 或者,你可能想要先清理混亂情況,然后再讓程序崩潰。 例如,你可能想要關閉與某個資源的連接,以免出現更多問題。

    (2)Go 提供內置函數?recover(),允許你在出現緊急狀況之后重新獲得控制權。

    (3)只能在已推遲的函數中使用此函數。

    (4)如果調用?recover()?函數,則在正常運行的情況下,它會返回?nil,沒有任何其他作用。

    兩者的關系:panic 與 recover 是 Go 的兩個內置函數,這兩個內置函數用于處理 Go 運行時的錯誤,panic 用于主動拋出錯誤,recover 用來捕獲 panic 拋出的錯誤。

    (1)引發?panic?有兩種情況,一是程序主動調用,二是程序產生運行時錯誤,由運行時檢測并退出;

    (2)發生?panic?后,程序會從調用?panic?的函數位置或發生?panic?的地方立即返回,逐層向上執行函數的?defer?語句,然后逐層打印函數調用堆棧,直到被?recover?捕獲或運行到最外層函數;

    (3)panic?不但可以在函數正常流程中拋出,在?defer?邏輯里也可以再次調用?panic?或拋出?panic;defer?里面的?panic?能夠被后續執行的?defer?捕獲;

    (4)recover?用來捕獲?panic,阻止?panic?繼續向上傳遞;

    (5)recover?和?defer?一起使用,但是?defer?只有在后面的函數體內直接被調用才能捕獲?panic?來終止異常,否則返回?nil,異常繼續向外傳遞。

    //以下三種方法捕獲失敗 defer recover() //無效 defer fmt.Prinntln(recover) //無效defer func(){func(){recover() //無效,嵌套兩層}() }()//以下三種捕獲有效 defer func(){recover() }()func except(){recover() }func test(){defer except()panic("runtime error") }

    7.9 示例:用戶登錄(流程控制)

    package main import "fmt" func main() {// 實現登錄驗證,有三次機會,如果用戶名和密碼正確提示登錄成功// 否則提示還有幾次機會var name string var pwd stringvar loginChance = 3for i := 1 ; i <= 3; i++ {fmt.Println("請輸入用戶名")fmt.Scanln(&name)fmt.Println("請輸入密碼")fmt.Scanln(&pwd)if name == "user" && pwd == "888888" {fmt.Println("恭喜你登錄成功!")break} else {loginChance--fmt.Printf("你還有%v次登錄機會,請珍惜\n", loginChance)}}if loginChance == 0 {fmt.Println("機會用完,沒有登錄成功!")} }

    7.10 示例:錯誤處理(控制流中斷)

    package mainimport "fmt"func main() {defer func() {if r := recover(); r != nil {fmt.Println("Recovered in main", r)}}()g(0)fmt.Println("Program finished successfully!") }func g(i int) {if i > 3 {fmt.Println("Panicking!")panic("Panic in g() (major)")}defer fmt.Println("Defer in g()", i)fmt.Println("Printing in g()", i)g(i + 1) }/* Printing in g() 0 Printing in g() 1 Printing in g() 2 Printing in g() 3 Panicking! Defer in g() 3 Defer in g() 2 Defer in g() 1 Defer in g() 0 Recovered in main Panic in g() (major) */

    下面是運行代碼時會發生的情況:

  • ?一切正常運行。 程序輸出?g()?函數接收的值。
  • 當?i?大于 3 時,程序會進入緊急狀態。 會顯示“Panicking!”消息。 此時,控制流中斷,所有推遲的函數都開始輸出“Defer in g()”消息。
  • 程序崩潰,并顯示?recover()?消息。?
  • 總結:

  • 在發生未預料到的嚴重錯誤時,系統通常會運行對?panic()?的調用。 若要避免程序崩潰,可以使用?recover()?函數。
  • 在?main()?函數中,你會將一個可以調用?recover()?函數的匿名函數推遲。
  • 當程序處于緊急狀態時,對?recover()?的調用無法返回?nil。 你可以在此處執行一些操作來清理混亂,但在這種情況下,你可以直接輸出一些內容。
  • panic()?和?recover()?的組合是 Go 處理異常的慣用方式。
  • ?

    八、數組

    數組是具有相同唯一類型的一組已編號且長度固定的數據項序列,這種類型可以是任意的原始類型例如整型、字符串或者自定義類型。

    8.1 聲明與初始化

    // Go 語言數組聲明需要指定元素類型及元素個數,語法格式如下: var variable_name [SIZE] variable_type// 一維數組的定義方式。例如以下定義了數組 balance 長度為 10 類型為 float32: var balance [10] float32// 數組初始化,初始化數組中 {} 中的元素個數不能大于 [] 中的數字: var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}// 如果數組長度不確定,可以使用 ... 代替數組的長度,編譯器會根據元素個數自行推斷數組的長度: var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0} //或 balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}// 如果設置了數組的長度,我們還可以通過指定下標來初始化元素: // 將索引為 1 和 3 的元素初始化 balance := [5]float32{1:2.0,3:7.0}// 常用的多維數組聲明方式: var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type// 以下實例聲明了三維的整型數組: var threedim [5][10][4]int// 二維數組初始化 a := [3][4]int{ {0, 1, 2, 3} , /* 第一行索引為 0 */{4, 5, 6, 7} , /* 第二行索引為 1 */{8, 9, 10, 11}, /* 第三行索引為 2 */ //注意:必須要有逗號,因為后面一行的?}?不能單獨一行。 }

    8.2 賦值與訪問

    數組元素可以通過索引(位置)來讀取。格式為數組名后加中括號,中括號中為索引的值。例如:

    package mainimport "fmt"func main() {var n [10]int /* n 是一個長度為 10 的數組 */var i,j int/* 為數組 n 初始化元素 */ for i = 0; i < 10; i++ {n[i] = i + 100 /* 設置元素為 i + 100 */}/* 輸出每個數組元素的值 */for j = 0; j < 10; j++ {fmt.Printf("Element[%d] = %d\n", j, n[j] )} }/* Element[0] = 100 Element[1] = 101 Element[2] = 102 Element[3] = 103 Element[4] = 104 Element[5] = 105 Element[6] = 106 Element[7] = 107 Element[8] = 108 Element[9] = 109 */

    二維數組:

    package mainimport "fmt"func main() {// Step 1: 創建數組values := [][]int{}// Step 2: 使用 appped() 函數向空的二維數組添加兩行一維數組row1 := []int{1, 2, 3}row2 := []int{4, 5, 6}values = append(values, row1)values = append(values, row2)// Step 3: 顯示兩行數據fmt.Println("Row 1")fmt.Println(values[0])fmt.Println("Row 2")fmt.Println(values[1])// Step 4: 訪問第一個元素fmt.Println("第一個元素為:")fmt.Println(values[0][0]) }/* Row 1 [1 2 3] Row 2 [4 5 6] 第一個元素為: 1 */

    使用函數修改數組的值:

    package main import ("fmt" )// 函數(數組) func test01(arr01 [3]int) {fmt.Println("arr01 arr old = ", arr01)arr01[0] = 88fmt.Println("arr01 arr new = ", arr01) } // 函數(數組指針) func test02(arr02 *[3]int) {fmt.Printf("arr02指針的值 = %p\n", arr02)fmt.Printf("arr02指針的地址 = %p\n", &arr02)fmt.Println("arr02 arr old = ", *arr02) (*arr02)[0] = 88 fmt.Println("arr02 arr new = ", *arr02) } func main() {arr := [3]int{11, 22, 33}fmt.Println("main arr old =", arr)test01(arr)fmt.Println("main arr from test01 =", arr)fmt.Println("----------以上傳的是數組,數組值沒有變化----------")fmt.Println("----------如果想修改數組,需要傳數組指針----------")fmt.Printf("arr 的地址 = %p\n", &arr)test02(&arr)fmt.Println("main arr from test02 =", arr) }/* main arr old = [11 22 33] arr01 arr old = [11 22 33] arr01 arr new = [88 22 33] main arr from test01 = [11 22 33] ----------以上傳的是數組,數組值沒有變化---------- ----------如果想修改數組,需要傳數組指針---------- arr 的地址 = 0xc0000a8120 arr02指針的值 = 0xc0000a8120 arr02指針的地址 = 0xc0000d4020 arr02 arr old = [11 22 33] arr02 arr new = [88 22 33] main arr from test02 = [88 22 33] */

    創建各個維度元素數量不一致的多維數組:

    package?mainimport?"fmt"func?main()?{// 創建空的二維數組animals?:=?[][]string{}// 創建三一維數組,各數組長度不同row1?:=?[]string{"fish",?"shark",?"eel"}row2?:=?[]string{"bird"}row3?:=?[]string{"lizard",?"salamander"}// 使用 append() 函數將一維數組添加到二維數組中animals?=?append(animals,?row1)animals?=?append(animals,?row2)animals?=?append(animals,?row3)// 循環輸出for?i?:=?range?animals?{fmt.Printf("Row: %v\n",?i)fmt.Println(animals[i])} }/* Row: 0 [fish shark eel] Row: 1 [bird] Row: 2 [lizard salamander] */

    8.3 range遍歷

    package main import ( "fmt" ) func main() { // 二維數組 var value = [3][2]int{{1, 2}, {3, 4}, {5, 6}} // 遍歷二維數組,使用 range // 其實,這里的 i, j 表示行游標和列游標 // v2 就是具體的每一個元素 // v 就是每一行的所有元素 for i, v := range value {for j, v2 := range v { fmt.Printf("value[%v][%v]=%v \t ", i, j, v2) } fmt.Print(v) fmt.Println() } }/* value[0][0]=1 value[0][1]=2 [1 2] value[1][0]=3 value[1][1]=4 [3 4] value[2][0]=5 value[2][1]=6 [5 6] */

    ?

    九、切片

    9.1 切片內部結構

    struct Slice { ??byte* ? ?array; ? ? ? // actual datauintgo ? ?len; ? ? ? ?// number of elementsuintgo ? ?cap; ? ? ? ?// allocated number of elements? };

    切片有 3 個組件:

    • 指針,指向基礎數組可訪問的第一個元素(并非一定是數組的第一個元素)。
    • 長度,指示切片中的元素數目,表示 slice 的長度。
    • 容量,顯示切片開頭與基礎數組結束之間的元素數目。

    下圖顯示了什么是切片:

    當把 slice 作為參數,本身傳遞的是值,但其內容就?byte* array,實際傳遞的是引用,所以可以在函數內部修改,但如果對 slice 本身做 append,而且導致 slice 進行了擴容,實際擴容的是函數內復制的一份切片,對于函數外面的切片沒有變化。

    9.2 切片項

    Go 支持切片運算符?s[i:j],其中:

    • s?表示數組。
    • i?表示指向它將使用的數組(或另一切片)的第一個元素的指針。
    • j?表示切片將使用的最后一個元素的位置。

    換句話說,切片只能引用元素的子集。

    例如,假設需要 4 個變量來表示一年的每個季度。 下圖說明了它在 Go 中的顯示效果:

    若要用代碼表示在上圖中看到的內容,可使用以下代碼:

    package mainimport "fmt"func main() {months := []string{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}quarter1 := months[0:3]quarter2 := months[3:6]quarter3 := months[6:9]quarter4 := months[9:12]fmt.Println(quarter1, len(quarter1), cap(quarter1))fmt.Println(quarter2, len(quarter2), cap(quarter2))fmt.Println(quarter3, len(quarter3), cap(quarter3))fmt.Println(quarter4, len(quarter4), cap(quarter4)) }/* [January February March] 3 12 [April May June] 3 9 [July August September] 3 6 [October November December] 3 3 */

    示例代碼:

    package mainimport "fmt"func main() {/* 創建切片 */numbers := []int{0,1,2,3,4,5,6,7,8} printSlice(numbers)/* 打印原始切片 */fmt.Println("numbers ==", numbers)/* 打印子切片從索引1(包含) 到索引4(不包含)*/fmt.Println("numbers[1:4] ==", numbers[1:4])/* 默認下限為 0*/fmt.Println("numbers[:3] ==", numbers[:3])/* 默認上限為 len(s)*/fmt.Println("numbers[4:] ==", numbers[4:])numbers1 := make([]int,0,5)printSlice(numbers1)/* 打印子切片從索引 0(包含) 到索引 2(不包含) */number2 := numbers[:2]printSlice(number2)/* 打印子切片從索引 2(包含) 到索引 5(不包含) */number3 := numbers[2:5]printSlice(number3)}func printSlice(x []int){fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x) }/* len=9 cap=9 slice=[0 1 2 3 4 5 6 7 8] numbers == [0 1 2 3 4 5 6 7 8] numbers[1:4] == [1 2 3] numbers[:3] == [0 1 2] numbers[4:] == [4 5 6 7 8] len=0 cap=5 slice=[] len=2 cap=9 slice=[0 1] len=3 cap=7 slice=[2 3 4] */

    9.3 append() 和 copy() 函數

    package mainimport "fmt"func main() {var numbers []intprintSlice(numbers)/* 允許追加空切片 */numbers = append(numbers, 0)printSlice(numbers)/* 向切片添加一個元素 */numbers = append(numbers, 1)printSlice(numbers)/* 同時添加多個元素 */numbers = append(numbers, 2,3,4)printSlice(numbers)/* 創建切片 numbers1 是之前切片的兩倍容量*/numbers1 := make([]int, len(numbers), (cap(numbers))*2)/* Go 具有內置函數 copy(dst, src []Type) 用于創建切片的副本。 * 創建一個切片副本,它會在后臺生成新的基礎數組,與原數組互不影響* 你需要發送目標切片和源切片,拷貝 numbers 的內容到 numbers1*/copy(numbers1,numbers)printSlice(numbers1) }func printSlice(x []int){fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x) }/* len=0 cap=0 slice=[] len=1 cap=1 slice=[0] len=2 cap=2 slice=[0 1] len=5 cap=6 slice=[0 1 2 3 4] len=5 cap=12 slice=[0 1 2 3 4] */

    9.4 容量cap變化規律

    /*每次cap改變的時候指向array內存的指針都在變化。當在使用 append 的時候,如果 cap==len 了這個時候就會新開辟一塊更大內存,然后把之前的數據復制過去。實際go在append的時候放大cap是有規律的。在 cap 小于1024的情況下是每次擴大到 2 * cap ,當大于1024之后就每次擴大到 1.25 * cap 。 */package mainimport ("fmt""unsafe" )func main() { // 每次cap改變,指向array的ptr就會變化一次s := make([]int, 1)fmt.Printf("len:%d cap: %d array ptr: %v \n", len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(&s)))for i := 0; i < 5; i++ {s = append(s, i)fmt.Printf("len:%d cap: %d array ptr: %v \n", len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(&s)))}fmt.Println("Array:", s) }/* len:1 cap: 1 array ptr: 0xc0000aa058 len:2 cap: 2 array ptr: 0xc0000aa0a0 len:3 cap: 4 array ptr: 0xc0000a8140 len:4 cap: 4 array ptr: 0xc0000a8140 len:5 cap: 8 array ptr: 0xc0000c20c0 len:6 cap: 8 array ptr: 0xc0000c20c0 Array: [0 0 1 2 3 4] */

    9.5 示例:斐波納契數列

    斐波那契數列(Fibonacci sequence),又稱黃金分割數列,因數學家萊昂納多·斐波那契(Leonardoda Fibonacci)以引入;

    指的是這樣一個數列:0、1、1、2、3、5、8、13、21、34、55、89、……

    在數學上,斐波那契數列以如下被以遞推的方法定義:F(0)=0,F(1)=1,?F(n)=F(n - 1)+F(n - 2)(n?≥ 2,n?∈ N*)
    ?

    package mainimport "fmt"func fibonacci(n int) []int {if n < 2 {return make([]int, 0)}nums := make([]int, n)nums[0], nums[1] = 1, 1for i := 2; i < n; i++ {nums[i] = nums[i-1] + nums[i-2]}return nums }func main() {var num intfmt.Print("What's the Fibonacci sequence you want? ")fmt.Scanln(&num)fmt.Println("The Fibonacci sequence is:", fibonacci(num)) }

    ?

    十、映射

    (1)Map 是一種無序的鍵值對的集合。

    (2)Map 最重要的一點是通過 key 來快速檢索數據,key 類似于索引,指向數據的值。

    (3)Map 是一種集合,可以像迭代數組和切片那樣迭代它。

    (4)Map 是無序的,我們無法決定它的返回順序,這是因為 Map 是使用 hash 表來實現的。

    10.1 定義 Map

    可以使用內建函數 make 也可以使用 map 關鍵字來定義 Map:

    /* 聲明變量,默認 map 是 nil ,nil map 不能用來存放鍵值對*/ var map_variable map[key_data_type]value_data_type/* 使用 make 函數 ,創建空映射,可以用來存放鍵值對*/ map_variable := make(map[key_data_type]value_data_type)/* 定義并初始化*/ studentsAge := map[string]int{"john": 32, "bob": 31,}

    10.2 添加與刪除

    delete() 函數用于刪除集合的元素, 參數為 map 和其對應的 key。實例如下:

    package mainimport "fmt"func main() {/* 創建map */countryCapitalMap := map[string]string{"France": "Paris", "Italy": "Rome"}/* 添加映射項 */countryCapitalMap ["Japan"] = "Tokyo"countryCapitalMap ["India"] = "New delhi"fmt.Println("原始地圖")/* 打印地圖 *//* 方法1:可以直接打印輸出映射fmt.Println(countryCapitalMap ) *//* 方法2:可使用for range打印輸出映射 */ for country := range countryCapitalMap {fmt.Println(country, "首都是", countryCapitalMap [ country ])}/* for range雙參數輸出for country , capital:= range countryCapitalMap {fmt.Printf("%s\t%s\n", country , capital)}*//*刪除元素*/ delete(countryCapitalMap, "France")fmt.Println("法國條目被刪除")fmt.Println("刪除元素后地圖")/*打印地圖*/for country := range countryCapitalMap {fmt.Println(country, "首都是", countryCapitalMap [ country ])} }/* 原始地圖 India 首都是 New delhi France 首都是 Paris Italy 首都是 Rome Japan 首都是 Tokyo 法國條目被刪除 刪除元素后地圖 Italy 首都是 Rome Japan 首都是 Tokyo India 首都是 New delhi */

    10.3 判斷存在

    訪問映射中沒有的項時 Go 不會返回錯誤,這是正常的。

    但有時需要知道某個項是否存在。 在 Go 中,映射的下標表示法可生成兩個值。 第一個是項的值。 第二個是指示鍵是否存在的布爾型標志。

    package mainimport "fmt"func main() {studentsAge := make(map[string]int)studentsAge["john"] = 32studentsAge["bob"] = 31age, exist := studentsAge["christy"]if exist {fmt.Println("Christy's age is", age)} else {fmt.Println("Christy's age couldn't be found")} }

    ?

    十一、結構體

    11.1?聲明和初始化

    /* 使用 struct 關鍵字,還要使用希望新的數據類型具有的字段及其類型的列表*/ type Employee struct {ID intFirstName stringLastName stringAddress string }/* 可像操作其他類型一樣使用新類型聲明一個變量*/ var john Employee/* * 可像操作其他類型一樣使用新類型聲明一個變量;* 請注意,該方式必須為結構中的每個字段指定一個值。 */ employee01 := Employee{1001, "John", "Doe", "Doe's Street"}/* * 可更具體地了解要在結構中初始化的字段。* 為每個字段分配值的順序不重要。 * 如果未指定任何其他字段的值,也并不重要。 Go 將根據字段數據類型分配默認值。 */ employee02 := Employee{LastName: "Doe", FirstName: "John"}

    11.2?結構嵌入

    有時,你需要減少重復并重用一種常見的結構。通過 Go 中的結構,可將某結構嵌入到另一結構中。

    package mainimport "fmt"type Person struct {ID intFirstName stringLastName stringAddress string }/* 第1種方法:重構結構體*/ type Employee struct {PersonManagerID int }/* 第2種方法:創建新字段*/ type Contractor struct {Information PersonCompanyID int }func main() {/** 第1種方法定義的使用* 無需指定 Person 字段的情況下訪問 Employee 結構中的 FirstName 字段,因為它會自動嵌入其所有字段。 * 但在你初始化結構時,必須明確要給哪個字段分配值*/employee := Employee{Person: Person{FirstName: "John",},}employee.LastName = "Doe"fmt.Println(employee.FirstName)/** 第2種方法定義的使用* 若要引用 Person 結構中的字段,你需要包含員工變量中的 Information 字段*/var contractor Contractor contractor.Information.FirstName = "John"fmt.Println(contractor.FirstName) }

    11.3 JSON 序列化

    可使用結構來對 JSON 中的數據進行編碼和解碼。 Go 對 JSON 格式提供很好的支持,該格式已包含在標準庫包中。

    JSON 編碼示例:

    package main import ("fmt""encoding/json" )type Monster struct {Name string `json:"monster_name"` // 結構體的 tag 標簽,反射機制Age int `json:"monster_age"`Birthday stringSal float64Skill string }// 將 struct 進行序列化 func testStruct() {monster := Monster{Name :"牛魔王",Age : 500 ,Birthday : "2011-11-11",Sal : 8000.0,Skill : "牛魔拳",}// 將 monster 序列化data, err := json.Marshal(&monster)if err != nil {fmt.Printf("序列號錯誤 err=%v\n", err)}// 輸出序列化后的結果fmt.Printf("monster序列化后 = %v\n", string(data)) }// 將 map 進行序列化 func testMap() {var a map[string]interface{}a = make(map[string]interface{})a["name"] = "紅孩兒"a["age"] = 30a["address"] = "洪崖洞"//將a這個 map 進行序列化data, err := json.Marshal(a)if err != nil {fmt.Printf("序列化錯誤 err=%v\n", err)}// 輸出序列化后的結果fmt.Printf("a map 序列化后 = %v\n", string(data)) }// 將切片進行序列化, []map[string]interface{} func testSlice() {var slice []map[string]interface{}var m1 map[string]interface{}m1 = make(map[string]interface{})m1["name"] = "jack"m1["age"] = "7"m1["address"] = "北京"slice = append(slice, m1)var m2 map[string]interface{}m2 = make(map[string]interface{})m2["name"] = "tom"m2["age"] = "20"m2["address"] = [2]string{"上海","深圳"}slice = append(slice, m2)// 將切片進行序列化操作data, err := json.Marshal(slice)if err != nil {fmt.Printf("序列化錯誤 err=%v\n", err)}// 輸出序列化后的結果fmt.Printf("slice 序列化后 = %v\n", string(data)) }// 對基本數據類型序列化,對基本數據類型進行序列化意義不大 func testFloat64() {var num1 float64 = 2345.67data, err := json.Marshal(num1)if err != nil {fmt.Printf("序列化錯誤 err=%v\n", err)}// 輸出序列化后的結果fmt.Printf("num1 序列化后 = %v\n", string(data)) }func main() {// 演示將結構體, map , 切片進行序列化testStruct()testMap()testSlice()testFloat64() }/* monster序列化后 = {"monster_name":"牛魔王","monster_age":500,"Birthday":"2011-11-11","Sal":8000,"Skill":"牛魔拳"} a map 序列化后 = {"address":"洪崖洞","age":30,"name":"紅孩兒"} slice 序列化后 = [{"address":"北京","age":"7","name":"jack"},{"address":["上海","深圳"],"age":"20","name":"tom"}] num1 序列化后 = 2345.67 */

    JSON 解碼示例:

    package main import ("fmt""encoding/json" )// 定義一個結構體 type Monster struct {Name string Age int Birthday string Sal float64Skill string }// 將 json 字符串,反序列化成 struct func unmarshalStruct() {// json str 一般不是直接寫入,在項目開發中,是通過網絡傳輸獲取到,或者是讀取文件獲取到str := "{\"Name\":\"牛魔王\",\"Age\":500,\"Birthday\":\"2011-11-11\",\"Sal\":8000,\"Skill\":\"牛魔拳\"}"var monster Monstererr := json.Unmarshal([]byte(str), &monster)if err != nil {fmt.Printf("unmarshal err=%v\n", err)}fmt.Printf("反序列化后 monster = %v monster.Name = %v \n", monster, monster.Name) }// 將 json 字符串,反序列化成 map func unmarshalMap() {str := "{\"address\":\"洪崖洞\",\"age\":30,\"name\":\"紅孩兒\"}"// 定義一個 mapvar a map[string]interface{} // 注意:反序列化 map,不需要 make,因為 make 操作被封裝到 Unmarshal 函數err := json.Unmarshal([]byte(str), &a)if err != nil {fmt.Printf("unmarshal err=%v\n", err)}fmt.Printf("反序列化后 map a = %v\n", a)}// 將 json 字符串,反序列化成切片 func unmarshalSlice() {str := "[{\"address\":\"北京\",\"age\":\"7\",\"name\":\"jack\"}," + "{\"address\":[\"上海\",\"深圳\"],\"age\":\"20\",\"name\":\"tom\"}]" //定義一個slicevar slice []map[string]interface{}//反序列化,不需要make,因為make操作被封裝到 Unmarshal函數err := json.Unmarshal([]byte(str), &slice)if err != nil {fmt.Printf("unmarshal err=%v\n", err)}fmt.Printf("反序列化后 slice = %v\n", slice) }func main() {unmarshalStruct()unmarshalMap()unmarshalSlice() }/* 反序列化后 monster = {牛魔王 500 2011-11-11 8000 牛魔拳} monster.Name = 牛魔王 反序列化后 map a = map[address:洪崖洞 age:30 name:紅孩兒] 反序列化后 slice = [map[address:北京 age:7 name:jack] map[address:[上海 深圳] age:20 name:tom]] */

    類型示例:

    package mainimport ("encoding/json""fmt" )/* 敲黑板,劃重點:當要將結構體對象轉換為 JSON 時,對象中的屬性首字母必須是大寫,才能正常轉換為 JSON。*/ type Person struct {ID intFirstName string `json:"name"` // JSON 輸出顯示 name 而不是 FirstName LastName stringAddress string `json:"address,omitempty"` // 忽略空字段 }type Employee struct {PersonManagerID int }func main() {employees := []Employee{Employee{Person: Person{LastName: "Doe", FirstName: "John",},},Employee{Person: Person{LastName: "Campbell", FirstName: "David",},},}data, _ := json.Marshal(employees) // 若要將結構編碼為 JSON,請使用 json.Marshal 函數fmt.Printf("%s\n", data)var decoded []Employeejson.Unmarshal(data, &decoded) // 若要將 JSON 字符串解碼為數據結構,請使用 json.Unmarshal 函數fmt.Printf("%v", decoded) }/* [{"ID":0,"name":"John","LastName":"Doe","ManagerID":0},{"ID":0,"name":"David","LastName":"Campbell","ManagerID":0}] [{{0 John Doe } 0} {{0 David Campbell } 0}] */

    ?

    十二、方法

    Go 中的方法是一種特殊類型的函數,但存在一個簡單的區別:你必須在函數名稱之前加入一個額外的參數。 此附加參數稱為?接收方

    如你希望分組函數并將其綁定到自定義類型,則方法非常有用。 Go 中的這一方法類似于在其他編程語言中創建類,因為它允許你實現面向對象編程 (OOP) 模型中的某些功能,例如嵌入、重載和封裝。

    12.1 聲明方法

    package mainimport "fmt"/* 在聲明方法之前,必須先創建結構*/ type triangle struct {size int }type square struct {size int }/* 附加的額外參數(t triangle)就是接收方*/ func (t triangle) perimeter() int {return t.size * 3 }/* 此方法屬于不同的結構,可以為其指定相同的名稱*/ func (s square) perimeter() int {return s.size * 4 }func main() {/* 如果嘗試按平常的方式調用 perimeter() 函數,則此函數將無法正常工作,因為此函數的簽名表明它需要接收方。* 因此,調用此方法的唯一方式是先聲明一個結構,獲取此方法的訪問權限。* 通過對 perimeter() 函數的兩次調用,編譯器將根據接收方類型來確定要調用的函數。* 這有助于在各程序包之間保持函數的一致性和名稱的簡短,并避免將包名稱作為前綴。*/t := triangle{3}s := square{4}fmt.Println("Perimeter (triangle):", t.perimeter())fmt.Println("Perimeter (square):", s.perimeter()) }/* Perimeter (triangle): 9 Perimeter (square): 16 */

    方法的一個關鍵方面在于,可以為任何類型定義方法,而不只是針對自定義類型(如結構)進行定義。 但是,你不能通過屬于其他包的類型來定義結構。 因此,不能在基本類型(如?string)上創建方法。

    12.2 方法的重載

    package mainimport "fmt"/* 結構體:三角形*/ type triangle struct {size int }/* 結構體:彩色三角形* 方法可以重用來自一個結構的屬性,以避免出現重復并保持代碼庫的一致性。 * 即使接收方不同,也可以調用已嵌入結構的方法。 */ type coloredTriangle struct {trianglecolor string }/* 三角形大小增加3倍*/ func (t triangle) perimeter() int {return t.size * 3 }/* 重載方法* 可以在 coloredTriangle 結構中更改 perimeter() 方法的實現* 因為方法需要額外參數(接收方),所以,可以使用一個同名的方法,只要此方法專門用于要使用的接收方即可。 */ func (t coloredTriangle) perimeter() int {return t.size * 3 * 2 }func main() {t := triangle{3} // 定義一個三角形fmt.Println("Perimeter (triangle):", t.perimeter())t1 := coloredTriangle{triangle{5}, "blue"} // 定義一個彩色三角形fmt.Println("Size:", t1.size)/* 如果沒有寫重載方法 func (t coloredTriangle) perimeter() int,此處會從 triangle 結構調用 perimeter() 方法,而不必重新創建彩色三角形的方法* 如果寫了重載方法 func (t coloredTriangle) perimeter() int,此處會從 coloredTriangle 結構調用 perimeter() 方法*/fmt.Println("Perimeter", t1.perimeter()) /* 如果你仍需要從 triangle 結構調用 perimeter() 方法,則可通過對其進行顯示訪問來執行此操作。*/fmt.Println("Perimeter (normal)", t1.triangle.perimeter()) }/* Perimeter (triangle): 9 Size: 5 Perimeter 30 Perimeter (normal) 15 */

    在 Go 中,你可以?重載?方法,并在需要時仍訪問?原始?方法。

    12.3 方法的封裝

    在 Go 中,只需使用大寫標識符,即可公開方法(public),使用非大寫的標識符將方法設為私有方法(private)。

    Go 中的封裝僅在程序包之間有效。 換句話說,你只能隱藏來自其他程序包的實現詳細信息,而不能隱藏程序包本身。

    比如,創建新程序包?geometry?:

    package geometrytype Triangle struct {size int }func (t *Triangle) doubleSize() {t.size *= 2 }func (t *Triangle) SetSize(size int) {t.size = size }func (t *Triangle) Perimeter() int {t.doubleSize()return t.size * 3 }

    你可以使用上述程序包,具體如下所示:

    func main() {t := geometry.Triangle{}t.SetSize(3)fmt.Println("Perimeter", t.Perimeter()) }

    此時你應獲得以下輸出:

    Perimeter 18

    如要嘗試從?main()?函數中調用?size?字段或?doubleSize()?方法,程序將死機,如下所示:

    func main() {t := geometry.Triangle{}t.SetSize(3)fmt.Println("Size", t.size)fmt.Println("Perimeter", t.Perimeter()) }

    在運行前面的代碼時,你將看到以下錯誤:

    ./main.go:12:23: t.size undefined (cannot refer to unexported field or method size)

    12.4 函數與方法的區別

    (1)含義不同

    • 函數function是?段具有獨?功能的代碼,可以被反復多次調?,從?實現代碼復?。??法method是?個類的?為功能,只有該類的對象才能調?。

    (2)?法有接受者,?函數?接受者

    • Go語?的?法method是?種作?于特定類型變量的函數,這種特定類型變量叫做Receiver(接受者、接收者、接收器);
    • 接受者的概念類似于傳統?向對象語?中的this或self關鍵字;
    • Go語?的接受者強調了?法具有作?對象,?函數沒有作?對象;
    • ?個?法就是?個包含了接受者的函數;
    • Go語?中, 接受者的類型可以是任何類型,不僅僅是結構體, 也可以是struct類型外的其他類型。

    (3)函數不可以重名,??法可以重名

    • 只要接受者不同,則?法名可以?樣。

    (4)調用方式不一樣

    • 方法由struct對象通過(.點號)調用,而函數是直接調用。
      ?

    十三、接口

    與其他編程語言中的接口不同,Go 中的接口是滿足隱式實現的。?

    示例:編寫自定義?String()?方法來打印自定義字符串,具體如下所示:

    package mainimport "fmt"type Person struct {Name, Country string }func (p Person) String() string {return fmt.Sprintf("%v is from %v", p.Name, p.Country) }func main() {rs := Person{"John Doe", "USA"}ab := Person{"Mark Collins", "United Kingdom"}fmt.Printf("%s\n%s\n", rs, ab) }/* John Doe is from USA Mark Collins is from United Kingdom */

    如你所見,你已使用自定義類型(結構)來寫入?String()?方法的自定義版本。 這是在 Go 中實現接口的一種常用方法。

    13.1 示例:interface聲明與使用方法

    package main import "fmt"// 聲明/定義一個接口 type Usb interface { Start() Stop() }type Phone struct {} // 讓Phone 實現 Usb接口的方法 func (p Phone) Start() {fmt.Println("手機開始工作。。。") } func (p Phone) Stop() {fmt.Println("手機停止工作。。。") }type Camera struct {}// 讓Camera 實現 Usb接口的方法 func (c Camera) Start() {fmt.Println("相機開始工作。。。") } func (c Camera) Stop() {fmt.Println("相機停止工作。。。") }// Computer,可以識別 Phone 和 Camera 的接口 type Computer struct {} /* 編寫一個 Working 方法,接收一個Usb接口類型變量* 該變量必須實現了 Usb 接口聲明的所有方法* 通過usb接口變量來調用Start和Stop方法* 這里實際體現了多態特性,因為同一個參數可以接收多個類型變量 */ func (c Computer) Working(usb Usb) {usb.Start() usb.Stop() }func main() {// 創建結構體變量computer := Computer{}phone := Phone{}camera := Camera{}// 接口的使用computer.Working(phone)computer.Working(camera) }/* 手機開始工作。。。 手機停止工作。。。 相機開始工作。。。 相機停止工作。。。*/

    13.2 示例:創建用于管理在線商店的程序包

    編寫一個程序,此程序使用自定義程序包來管理在線商店的帳戶。

  • 創建一個名為?Account?的自定義類型,此類型包含帳戶所有者的名字和姓氏。 此類型還必須加入?ChangeName?的功能。

  • 創建另一個名為?Employee?的自定義類型,此類型包含用于將貸方數額存儲為類型?float64?并嵌入?Account?對象的變量。 類型還必須包含?AddCredits、RemoveCredits?和?CheckCredits?的功能。 你需要展示你可以通過?Employee?對象更改帳戶名稱。

  • 將字符串方法寫入?Account?對象,以便按包含名字和姓氏的格式打印?Employee?名稱。

  • 最后,編寫使用已創建程序包的程序,并測試此挑戰中列出的所有功能。 也就是說,主程序應更改名稱、打印名稱、添加貸方、刪除貸方以及檢查余額。

  • 下方是適用于商店程序包的代碼:

    package storeimport ("errors""fmt" )type Account struct {FirstName stringLastName string }type Employee struct {AccountCredits float64 }func (a *Account) ChangeName(newname string) {a.FirstName = newname }func (e Employee) String() string {return fmt.Sprintf("Name: %s %s\nCredits: %.2f\n", e.FirstName, e.LastName, e.Credits) }func CreateEmployee(firstName, lastName string, credits float64) (*Employee, error) {return &Employee{Account{firstName, lastName}, credits}, nil }func (e *Employee) AddCredits(amount float64) (float64, error) {if amount > 0.0 {e.Credits += amountreturn e.Credits, nil}return 0.0, errors.New("Invalid credit amount.") }func (e *Employee) RemoveCredits(amount float64) (float64, error) {if amount > 0.0 {if amount <= e.Credits {e.Credits -= amountreturn e.Credits, nil}return 0.0, errors.New("You can't remove more credits than the account has.")}return 0.0, errors.New("You can't remove negative numbers.") }func (e *Employee) CheckCredits() float64 {return e.Credits }

    下方是主程序用于測試所有功能的代碼:

    package mainimport ("fmt""store" )func main() {bruce, _ := store.CreateEmployee("Bruce", "Lee", 500)fmt.Println(bruce.CheckCredits())credits, err := bruce.AddCredits(250)if err != nil {fmt.Println("Error:", err)} else {fmt.Println("New Credits Balance = ", credits)}_, err = bruce.RemoveCredits(2500)if err != nil {fmt.Println("Can't withdraw or overdrawn!", err)}bruce.ChangeName("Mark")fmt.Println(bruce) }

    13.3 示例:通過實現接口對結構體切片進行排序

    package main import ("fmt""sort""math/rand" )type Hero struct{ // 聲明Hero結構體Name stringAge int }type HeroSlice []Hero // 聲明一個Hero結構體切片類型// 實現Interface 接口1(sort.Sort要求) func (hs HeroSlice) Len() int {return len(hs) }// 實現Interface 接口2(sort.Sort要求) // Less方法就是決定你使用什么標準進行排序 func (hs HeroSlice) Less(i, j int) bool {return hs[i].Age < hs[j].Age // 按Hero的Age從小到大排序//return hs[i].Name < hs[j].Name // 按Hero的Name排序,實際上可以按結構體的任意字段進行排序 }// 實現Interface 接口3(sort.Sort要求) func (hs HeroSlice) Swap(i, j int) {hs[i], hs[j] = hs[j], hs[i] // 交換 }func main() { var intSlice = []int{0, -1, 10, 7, 90} // 定義一個數組/切片sort.Ints(intSlice) // 對 intSlice切片進行排序,可以使用系統提供的一般方法fmt.Println(intSlice)/* 對結構體切片進行排序,本代碼重點內容 */var heroes HeroSlice // 定義一個切片for i := 0; i < 10 ; i++ { // 給切片賦值hero := Hero{Name : fmt.Sprintf("英雄|%d", rand.Intn(100)),Age : rand.Intn(100),}heroes = append(heroes, hero) // 將 hero append到 heroes切片}for _ , v := range heroes { // 排序前的順序fmt.Println(v)}sort.Sort(heroes) // 調用sort.Sort,必須實現interface,才可以調用fmt.Println("-----------排序后------------")for _ , v := range heroes { // 排序后的順序fmt.Println(v)}}/* [-1 0 7 10 90] {英雄|81 87} {英雄|47 59} {英雄|81 18} {英雄|25 40} {英雄|56 0} {英雄|94 11} {英雄|62 89} {英雄|28 74} {英雄|11 45} {英雄|37 6} -----------排序后------------ {英雄|56 0} {英雄|37 6} {英雄|94 11} {英雄|81 18} {英雄|25 40} {英雄|11 45} {英雄|47 59} {英雄|28 74} {英雄|81 87} {英雄|62 89} */

    sort.Interface接口的說明:

    // https://studygolang.com/pkgdoc type Interface interface {// Len方法返回集合中的元素個數Len() int// Less方法報告索引i的元素是否比索引j的元素小Less(i, j int) bool// Swap方法交換索引i和j的兩個元素Swap(i, j int) }

    一個滿足sort.Interface接口的(集合)類型可以被本包的函數進行排序。方法要求集合中的元素可以被整數索引。

    ?

    十四、類型斷言

    golang中的所有程序都實現了interface{}的接口,這意味著,所有的類型如 string , int , int64 甚至是自定義的 struct 類型都就此擁有了 interface{} 的接口。

    類型斷言(Type Assertion)是一個使用在接口值上的操作,用于檢查接口類型變量所持有的值是否實現了期望的接口或者具體的類型。

    在Go語言中類型斷言的語法格式如下:

    value, ok := x.(T)

    其中,x 表示一個接口的類型,T 表示一個具體的類型(也可為接口類型)。

    該斷言表達式會返回 x 的值(也就是 value)和一個布爾值(也就是 ok),可根據該布爾值判斷 x 是否為 T 類型:

    • 如果 T 是具體某個類型,類型斷言會檢查 x 的動態類型是否等于具體類型 T。如果檢查成功,類型斷言返回的結果是 x 的動態值,其類型是 T。
    • 如果 T 是接口類型,類型斷言會檢查 x 的動態類型是否滿足 T。如果檢查成功,x 的動態值不會被提取,返回值是一個類型為 T 的接口值。
    • 無論 T 是什么類型,如果 x 是 nil 接口值,類型斷言都會失敗。
    package main import "fmt"type Point struct {x inty int }func main() {var a interface{}var point Point = Point{1, 2}a = point var b Pointb = a.(Point) // 直接進行類型斷言fmt.Println(b) var x interface{}var b2 float32 = 2.1x = b2 // 空接口,可以接收任意類型// 類型斷言(帶檢測的)if y, ok := x.(float32); ok {fmt.Println("convert success")fmt.Printf("y 的類型是, %T 值是 %v\n", y, y)} else {fmt.Println("convert fail")}s := "hello world"if v, ok := interface{}(s).(string); ok {fmt.Println(v)}fmt.Println("繼續執行...") }/* {1 2} convert success y 的類型是 float32, 值是 2.1 hello world 繼續執行... */

    接口變量的類型也可以使用一種特殊形式的 swtich 來檢測。下面的代碼片段展示了一個類型分類函數,它有一個可變長度參數,可以是任意類型的數組,它會根據數組元素的實際類型執行不同的動作:

    func classifier(items ...interface{}) {for i, x := range items {switch x.(type) {case bool:fmt.Printf("Param #%d is a bool\n", i)case float64:fmt.Printf("Param #%d is a float64\n", i)case int, int64:fmt.Printf("Param #%d is a int\n", i)case nil:fmt.Printf("Param #%d is a nil\n", i)case string:fmt.Printf("Param #%d is a string\n", i)default:fmt.Printf("Param #%d is unknown\n", i)}} }

    ?

    十五、隨機數

    真隨機和偽隨機概念:

  • 統計學偽隨機性:在給定的隨機比特流樣本中,1 的數量大致等于 0 的數量,也就是說,“10”“01”“00”“11” 四者數量大致相等。說人話就是:“一眼看上去是隨機的”。
  • 密碼學安全偽隨機性:就是給定隨機樣本的一部分和隨機算法,不能有效的演算出隨機樣本的剩余部分。
  • 真隨機性:其定義為隨機樣本不可重現。
  • 根據以上幾個標準,其對應的隨機數也就分為以下幾類:

  • 偽隨機數:滿足第一個條件的隨機數。
  • 密碼學安全的偽隨機數:同時滿足前兩個條件的隨機數。可以通過密碼學安全偽隨機數生成器計算得出
  • 真隨機數:同時滿足三個條件的隨機數
  • 15.1 偽隨機示例:math/rand

    rand包實現了偽隨機數生成器。

    隨機數從資源生成。包水平的函數都使用的默認的公共資源。該資源會在程序每次運行時都產生確定的序列。

    如果需要每次運行產生不同的序列,應使用Seed函數進行初始化。

    默認資源可以安全的用于多go程并發。

    package main import ("fmt""math/rand""time" )func main() {// 返回一個取值范圍在[0,n)的偽隨機int值,如果n<=0會panic // func Intn(n int) intrand1 := rand.Intn(100) //每次生成一個確定的值fmt.Println("rand1 = ", rand1)// 設置種子,使用給定的seed將默認資源初始化到一個確定的狀態;如未調用Seed,默認資源的行為就好像調用了Seed(1)// func Seed(seed int64)// Unix將t表示為Unix時間,即從時間點January 1, 1970 UTC到時間點t所經過的時間(單位秒)// func (t Time) Unix() int64for i:=1; i<=10; i++{rand.Seed(time.Now().Unix())rand2 := rand.Intn(100)fmt.Println("rand2 = ", rand2)}// UnixNano將t表示為Unix時間,即從時間點January 1, 1970 UTC到時間點t所經過的時間(單位納秒)// func (t Time) UnixNano() int64for i:=1; i<=10; i++{rand.Seed(time.Now().UnixNano())rand3 := rand.Intn(100)fmt.Println("rand3 = ", rand3)}}/* rand1 = 81 //每次運行均輸出該值 rand2 = 61 //每秒內輸出相同的值 rand2 = 61 rand2 = 61 rand2 = 61 rand2 = 61 rand2 = 61 rand2 = 61 rand2 = 61 rand2 = 61 rand2 = 61 rand3 = 95 //每納秒內輸出相同的值 rand3 = 95 rand3 = 95 rand3 = 82 rand3 = 82 rand3 = 82 rand3 = 82 rand3 = 82 rand3 = 82 rand3 = 93 */

    15.2 真隨機示例:crypto/rand

    package mainimport ("crypto/rand""fmt""math/big" )// crypto/rand包實現了用于加解密的更安全的隨機數生成器 // 返回一個在[0, max)區間服從均勻分布的隨機值,如果max<=0則會panic // func Int(rand io.Reader, max *big.Int) (n *big.Int, err error)func main() {// 生成 10 個 [0, 100) 范圍的真隨機數for i := 0; i < 10; i++ {result, _ := rand.Int(rand.Reader, big.NewInt(100))fmt.Println(result)} }/* 36 45 17 24 63 19 28 66 38 50 */

    ?

    十六、日期與時間

    time包提供了時間的顯示和測量用的函數。日歷的計算采用的是公歷。

    16.1 type Time

    type Time struct {// 內含隱藏或非導出字段 }

    (1)Time代表一個納秒精度的時間點;

    (2)程序中應使用Time類型值來保存和傳遞時間,而不能用指針。就是說,表示時間的變量和字段,應為 time.Time 類型,而不是 *time.Time. 類型;

    (3)一個Time類型值可以被多個go程同時使用;

    (4)時間點可以使用 Before、After 和 Equal 方法進行比較;

    (5)Sub方法讓兩個時間點相減,生成一個 Duration 類型值(代表時間段);

    (6)Add方法給一個時間點加上一個時間段,生成一個新的Time類型時間點;

    (7)Time零值代表時間點January 1, year 1, 00:00:00.000000000 UTC;因為本時間點一般不會出現在使用中,IsZero方法提供了檢驗時間是否顯式初始化的一個簡單途徑。

    (8)每一個時間都具有一個地點信息(及對應地點的時區信息),當計算時間的表示格式時,如 Format、Hour 和 Year 等方法,都會考慮該信息。Local、UTC和In方法返回一個指定時區(但指向同一時間點)的Time。修改地點/時區信息只是會改變其表示;不會修改被表示的時間點,因此也不會影響其計算。

    16.2 示例:日期與時間

    package main import ("fmt""time" )func main() {// 日期和時間相關函數和方法使用// 1. 獲取當前時間now := time.Now()fmt.Printf("now=%v now type=%T\n", now, now)// 2.通過now可以獲取到年月日,時分秒fmt.Printf("年=%v\n", now.Year())fmt.Printf("月=%v\n", now.Month()) //月份默認顯示類型fmt.Printf("月=%v\n", int(now.Month())) //月份類型轉換fmt.Printf("日=%v\n", now.Day())fmt.Printf("時=%v\n", now.Hour())fmt.Printf("分=%v\n", now.Minute())fmt.Printf("秒=%v\n", now.Second())fmt.Printf("星期=%v\n", now.Weekday())fmt.Println(now.Date()) //日期,返回三個參數fmt.Println(now.Clock()) //時間,返回三個參數// 3.格式化日期時間fmt.Printf("當前日期和時間 %d-%d-%d %d:%d:%d \n", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())dateStr := fmt.Sprintf("當前日期和時間 %d-%d-%d %d:%d:%d \n", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())fmt.Printf("dateStr=%v\n", dateStr)// 格式化日期時間的第二種方式// Format根據layout指定的格式返回t代表的時間點的格式化文本表示。layout定義了參考時間:// Mon Jan 2 15:04:05 -0700 MST 2006fmt.Printf(now.Format("2006-01-02 15:04:05"))fmt.Println()fmt.Printf(now.Format("2006-01-02"))fmt.Println()fmt.Printf(now.Format("15:04:05"))fmt.Println()fmt.Printf(now.Format("2006"))fmt.Println()// 4.每隔0.1秒中打印一個數字,打印到10時就退出i := 0for {i++fmt.Println(i)// time.Sleep(time.Second) // 休眠,每1秒time.Sleep(time.Millisecond * 100) // 休眠,每0.1秒if i == 10 {break}}// 5.Unix和UnixNano的使用fmt.Printf("unix時間戳 = %v\nunixnano時間戳 = %v\n", now.Unix(), now.UnixNano())}

    16.3 type Duration

    type Duration int64

    Duration類型代表兩個時間點之間經過的時間,以納秒為單位。可表示的最長時間段大約290年。

    const (Nanosecond Duration = 1Microsecond = 1000 * NanosecondMillisecond = 1000 * MicrosecondSecond = 1000 * MillisecondMinute = 60 * SecondHour = 60 * Minute )

    常用的時間段。沒有定義一天或超過一天的單元,以避免夏時制的時區切換的混亂。

    要將Duration類型值表示為某時間單元的個數,用除法:

    second := time.Second fmt.Print(int64(second/time.Millisecond)) // prints 1000

    要將整數個某時間單元表示為Duration類型值,用乘法:

    seconds := 10 fmt.Print(time.Duration(seconds)*time.Second) // prints 10s

    ?

    十七、cmd編譯

    17.1 兩種編譯方法

    主要有兩種 cmd 編譯方法:

    (1)go build:用于測試編譯包,在項目目錄下生成可執行文件(有main包)

    (2)go install:主要用來生成庫和工具

    • 一是編譯包文件(無main包),將編譯后的包文件放到 pkg 目錄下($GOPATH/pkg)。
    • 二是編譯生成可執行文件(有main包),將可執行文件放到 bin 目錄($GOPATH/bin)。

    相同點

    • 都能生成可執行文件

    不同點

    • go build 不能生成包文件, go install 可以生成包文件
    • go build 生成可執行文件默認在當前目錄下(可以通過參數指定生成目錄), go install 生成可執行文件默認在bin目錄下($GOPATH/bin)

    17.2 go build命令

    go build [-o 輸出名] [-i] [編譯標記] [包名]

    (1)如果參數為***.go文件或文件列表,則編譯為一個個單獨的包;

    (2)當編譯單個main包(文件),則生成可執行文件;

    (3)當編譯單個或多個包非主包時,只構建編譯包,但丟棄生成的對象(.a),僅用作檢查包可以構建;

    (4)當編譯包時,會自動忽略'_test.go'的測試文件。

    17.3 go build示例

    代碼相對于 GOPATH 的目錄關系如下:

    D:\golang\.|└── src├─── chapter11| └──── utils| └──── gobuild| ├──── lib.go| └──── main.go└─── chapter12└──── event└──── main.go

    (1)如果源碼中沒有依賴 GOPATH 的包引用,那么這些源碼可以使用無參數 go build

    // 在代碼所在目錄(./src/chapter11/gobuild)下使用 go build 命令 > cd src/chapter11/gobuild/ > go build
    • go build 在編譯開始時,會搜索當前目錄的 go 源碼。這個例子中,go build 會找到 lib.go 和 main.go 兩個文件。
    • 編譯這兩個文件后,生成當前目錄名的可執行文件并放置于當前目錄下,這里生成的可執行文件是 gobuild.exe 。

    (2)編譯同目錄的多個源碼文件時,可以在 go build 的后面提供多個文件名,go build 會編譯這些源碼,輸出可執行文件

    > cd src/chapter11/gobuild/> go build main.go lib.go //編譯結果,生成main.exe > go build lib.go main.go //編譯結果,生成lib.exe > go build -o test.exe main.go lib.go //編譯結果,生成test.exe
    • 使用“go build+文件列表”方式編譯時,可執行文件默認選擇文件列表中第一個源碼文件作為可執行文件名輸出。
    • 使用“go build+文件列表”方式編譯時,文件列表中的每個文件必須是同一個包的 Go 源碼。

    (3)“go build+包”方式編譯;在設置 GOPATH 后,可以直接根據包名進行編譯

    D:\> cd golangD:\golang> go build chapter11/gobuild // 后面接要編譯的包名;包名是相對于 GOPATH 下的 src 目錄開始的,生成默認的文件名 main.exe,保存在目錄 GOPATH 下 D:\golang> go build -o test.exe chapter11/gobuild // -o執行指定輸出文件名為 test.exe,保存在目錄 GOPATH 下 D:\golang> go build -o bin/test.exe chapter11/gobuild // -o執行指定輸出目錄bin(GOPATH/bin),輸出文件名為 test.exe

    注意 :GOPATH 下的目錄結構,源碼必須放在 GOPATH 下的 src 目錄下。所有目錄中不要包含中文。

    17.4 go install命令

    (1)go install 命令的功能和?go build 命令類似,附加參數絕大多數都可以與 go build 通用。

    (2)go install 只是將編譯的中間文件放在 GOPATH 的 pkg 目錄下,以及固定地將編譯結果放在 GOPATH 的 bin 目錄下。

    (3)這個命令在內部實際上分成了兩步操作:

    • 第一步是生成結果文件(可執行文件或者 .a 包),
    • 第二步會把編譯好的結果移到 $GOPATH/pkg 或者 $GOPATH/bin。
    go install [包名]

    go install 的編譯過程有如下規律:

    (1)go install 是建立在 GOPATH 上的,無法在獨立的目錄里使用 go install;

    (2)GOPATH 下的 bin 目錄放置的是使用 go install 生成的可執行文件,可執行文件的名稱來自于編譯時的包名;

    (3)go install 輸出目錄始終為 GOPATH 下的 bin 目錄,無法使用?-o?附加參數進行自定義;

    (4)GOPATH 下的 pkg 目錄放置的是編譯期間的中間文件。

    17.5 go install示例

    D:\> cd golangD:\golang> go install chapter11/gobuild

    編譯完成后的目錄結構如下:

    D:\golang\.|├── bin│ └─── gobuild.exe|├── pkg│ └─── chapter11│ └─── gobuild│ └── lib.a|└── src├─── chapter11| └──── utils| └──── gobuild| ├──── lib.go| └──── main.go└─── chapter12└──── event└──── main.go

    ?

    十八、錯誤處理策略

    Go 的錯誤處理方法只是一種只需要?if?和?return?語句的控制流機制。

    18.1 示例

    package mainimport ("fmt""os" )type Employee struct {ID intFirstName stringLastName stringAddress string }func main() {employee, err := getInformation(1001)if err != nil {// Something is wrong. Do something.} else {fmt.Print(employee)} }func getInformation(id int) (*Employee, error) {employee, err := apiCallEmployee(1000)return employee, err }func apiCallEmployee(id int) (*Employee, error) {employee := Employee{LastName: "Doe", FirstName: "John"}return &employee, nil }

    18.2 處理策略:

    當函數返回錯誤時,該錯誤通常是最后一個返回值。 正如上一部分所介紹的那樣,調用方負責檢查是否存在錯誤并處理錯誤。 因此,一個常見策略是繼續使用該模式在子例程中傳播錯誤。 例如,子例程(如上一示例中的?getInformation)可能會將錯誤返回給調用方,而不執行其他任何操作,如下所示:

    func getInformation(id int) (*Employee, error) {employee, err := apiCallEmployee(1000)if err != nil {return nil, err // Simply return the error to the caller.}return employee, nil }

    你可能還需要在傳播錯誤之前添加更多信息。 為此,可以使用?fmt.Errorf()?函數,該函數與我們之前看到的函數類似,但它返回一個錯誤。 例如,你可以向錯誤添加更多上下文,但仍返回原始錯誤,如下所示:

    func getInformation(id int) (*Employee, error) {employee, err := apiCallEmployee(1000)if err != nil {return nil, fmt.Errorf("Got an error when getting the employee information: %v", err)}return employee, nil }

    另一種策略是在錯誤為暫時性錯誤時運行重試邏輯。 例如,可以使用重試策略調用函數三次并等待兩秒鐘,如下所示:

    func getInformation(id int) (*Employee, error) {for tries := 0; tries < 3; tries++ {employee, err := apiCallEmployee(1000)if err == nil {return employee, nil}fmt.Println("Server is not responding, retrying ...")time.Sleep(time.Second * 2)}return nil, fmt.Errorf("server has failed to respond to get the employee information") }

    最后,可以記錄錯誤并對最終用戶隱藏任何實現詳細信息,而不是將錯誤打印到控制臺。

    創建可重用的錯誤:

    有時錯誤消息數會增加,你需要維持秩序。 或者,你可能需要為要重用的常見錯誤消息創建一個庫。 在 Go 中,你可以使用 errors.New() 函數創建錯誤并在若干部分中重復使用這些錯誤,如下所示:

    var ErrNotFound = errors.New("Employee not found!")func getInformation(id int) (*Employee, error) {if id != 1001 {return nil, ErrNotFound}employee := Employee{LastName: "Doe", FirstName: "John"}return &employee, nil }

    在 Go 中處理錯誤時,請記住下面一些推薦做法:

    • 始終檢查是否存在錯誤,即使預期不存在。 然后正確處理它們,以免向最終用戶公開不必要的信息。
    • 在錯誤消息中包含一個前綴,以便了解錯誤的來源。 例如,可以包含包和函數的名稱。
    • 創建盡可能多的可重用錯誤變量。
    • 了解使用返回錯誤和 panic 之間的差異。 不能執行其他操作時再使用 panic。 例如,如果某個依賴項未準備就緒,則程序運行無意義(除非你想要運行默認行為)。
    • 在記錄錯誤時記錄盡可能多的詳細信息,并打印出最終用戶能夠理解的錯誤。

    ?

    十九、日志記錄

    19.1 log包

    Go 提供了一個用于處理日志的簡單標準包。 可以像使用?fmt?包一樣使用此包。 該標準包不提供日志級別,且不允許為每個包配置單獨的記錄器。 如果需要編寫更復雜的日志記錄配置,可以使用記錄框架執行此操作。?

    log.Print()?函數將日期和時間添加為日志消息的前綴。

    import ("log" )func main() {log.Print("Hey, I'm a log!") }/* 2020/12/19 13:39:17 Logging in Go! */

    log.Fatal()?函數記錄錯誤并結束程序,就像使用?os.Exit(1)?一樣。

    package mainimport ("fmt""log" )func main() {log.Fatal("Hey, I'm an error log!")fmt.Print("Can you see me?") }/* 2020/12/19 13:53:19 Hey, I'm an error log! exit status 1 */

    注意最后一行?fmt.Print("Can you see me?")?未運行。 這是因為?log.Fatal()?函數調用停止了該程序。

    在使用?log.Panic()?函數時會出現類似行為,該函數也調用?panic()?函數,如下所示:

    package mainimport ("fmt""log" )func main() {log.Panic("Hey, I'm an error log!")fmt.Print("Can you see me?") }/* 2020/12/19 13:53:19 Hey, I'm an error log! panic: Hey, I'm an error log!goroutine 1 [running]: log.Panic(0xc000060f58, 0x1, 0x1)/usr/local/Cellar/go/1.15.5/libexec/src/log/log.go:351 +0xae main.main()/Users/christian/go/src/helloworld/logs.go:9 +0x65 exit status 2 */

    你仍獲得日志消息,但現在還會獲得錯誤堆棧跟蹤。

    另一重要函數是?log.SetPrefix()。 可使用它向程序的日志消息添加前綴。 例如,可以使用以下代碼片段:

    package mainimport ("log" )func main() {log.SetPrefix("main(): ")log.Print("Hey, I'm a log!")log.Fatal("Hey, I'm an error log!") }/* main(): 2021/01/05 13:59:58 Hey, I'm a log! main(): 2021/01/05 13:59:58 Hey, I'm an error log! exit status 1 */

    19.2 記錄到文件

    除了將日志打印到控制臺之外,你可能還希望將日志發送到文件,以便稍后或實時處理這些日志。

    為什么想要將日志發送到文件? 首先,你可能想要對最終用戶隱藏特定信息。 他們可能對這些信息不感興趣,或者你可能公開了敏感信息。 在文件中添加日志后,可以將所有日志集中在一個位置,并將它們與其他事件關聯。 此模式為典型模式:具有可能是臨時的分布式應用程序,例如容器。

    讓我們使用以下代碼測試將日志發送到文件:

    package mainimport ("log""os" )func main() {file, err := os.OpenFile("info.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)if err != nil {log.Fatal(err)}defer file.Close()log.SetOutput(file)log.Print("Hey, I'm a log!") }

    運行前面的代碼時,在控制臺中看不到任何內容。 在目錄中,你應看到一個名為 info.log 的新文件,其中包含使用?log.Print()?函數發送的日志。 請注意,需要首先創建或打開文件,然后將?log?包配置為將所有輸出發送到文件。 然后,可以像通常做法那樣繼續使用?log.Print()?函數。

    ?

    二十、反射

    示例:

    package main import ("fmt""reflect" )// 定義了一個Monster結構體 type Monster struct {Name string `json:"name"`Age int `json:"monster_age"`Score float32 Sex string}// 方法的排序默認是按照函數名的排序(ASCII碼) // 方法,返回兩個數的和,在 3 個方法中排第1,標號0 func (s Monster) GetSum(n1, n2 int) int {return n1 + n2 } // 方法, 接收四個值,給s賦值,在 3 個方法中排第3,標號2 func (s Monster) Set(name string, age int, score float32, sex string) {s.Name = names.Age = ages.Score = scores.Sex = sex }// 方法,顯示s的值,在 3 個方法中排第2,標號1 func (s Monster) Print() {fmt.Println("------start------")fmt.Println(s)fmt.Println("-------end-------") }func TestStruct(a interface{}) {typ := reflect.TypeOf(a) // 獲取reflect.Type 類型fmt.Println("reflect.TypeOf",typ)val := reflect.ValueOf(a) // 獲取reflect.Value 類型fmt.Println("reflect.ValueOf",val)kd := val.Kind() // 獲取到a對應的類別fmt.Println("val.Kind",kd)fmt.Println()if kd != reflect.Struct { // 如果傳入的不是struct,就退出fmt.Println("expect struct")return}num := val.NumField() // 獲取到該結構體有幾個字段fmt.Printf("struct has %d fields\n", num) // 變量結構體的所有字段for i := 0; i < num; i++ {fmt.Printf("Field %d: 值為=%v\n", i, val.Field(i)) // 獲取到該結構體的字段tagVal := typ.Field(i).Tag.Get("json") // 獲取到struct標簽, 注意需要通過reflect.Type來獲取tag標簽的值if tagVal != "" { // 如果該字段有tag標簽就顯示,否則就不顯示fmt.Printf("Field %d: tag為=%v\n", i, tagVal)}} fmt.Println()numOfMethod := val.NumMethod() // 獲取到該結構體有多少個方法fmt.Printf("struct has %d methods\n", numOfMethod)val.Method(1).Call(nil) // 調用第 2 個方法;方法的排序默認是按照 函數名的排序(ASCII碼)// 調用結構體的第1個方法Method(0)var params []reflect.Value // 聲明了 []reflect.Valueparams = append(params, reflect.ValueOf(10))params = append(params, reflect.ValueOf(40))res := val.Method(0).Call(params) // 傳入的參數是 []reflect.Value, 返回[]reflect.Valuefmt.Println("res=", res[0].Int()) // 返回結果, 返回的結果是 []reflect.Value }func main() {//創建了一個Monster實例var a Monster = Monster{Name: "huangshulang",Age: 400,Score: 30.8,}//將Monster實例傳遞給TestStruct函數TestStruct(a) }/* reflect.TypeOf main.Monster reflect.ValueOf {huangshulang 400 30.8 } val.Kind structstruct has 4 fields Field 0: 值為=huangshulang Field 0: tag為=name Field 1: 值為=400 Field 1: tag為=monster_age Field 2: 值為=30.8 Field 3: 值為=struct has 3 methods ------start------ {huangshulang 400 30.8 } -------end------- res= 50 */

    ?

    二十一、nil

    (1)nil 指針解引用會令程序崩潰;

    (2)方法可以通過簡單的措施類防范接收 nil 值;

    示例:

    package mainimport "fmt"// 定義一個結構體 type person struct{age int }// 結構體方法中,處理nil func (p *person) birthday(){if p != nil {p.age++} }func main(){// 普通指針var nowhere *intfmt.Println(nowhere) // nil//fmt.Println(*nowhere) // panic.go //go:nosplitif nowhere != nil{ // 解決方法fmt.Println(*nowhere)} // 結構體var nobody *personfmt.Println(nobody) // nilnobody.birthday() // 如果方法中沒有處理nil,panic.go// 函數var fn func(a,b int) intfmt.Println(fn == nil) // true,因為 fn 沒有被賦予任何函數// 切片var soup []stringfmt.Println(soup == nil) // true fmt.Println(len(soup)) // len 可以處理 nil 切片for _,ingredient := range soup{ // range 可以處理 nil 切片fmt.Println(ingredient) // 0}soup = append(soup,"onion","celery") // append 可以處理 nil 切片fmt.Println(soup) // [onion celery]// 接口var v interface{} // 接口變量的值和類型都是 nil,該變量是 nilfmt.Printf("%T %v %v \n",v,v,v == nil) // nil nil truevar p *intv = p // 接口變量的值是 nil,但類型不是nil,該變量就不是 nilfmt.Printf("%T %v %v \n",v,v,v == nil) // *int nil false }/* <nil> <nil> true true 0 [onion celery] <nil> <nil> true *int <nil> false */

    ?

    總結

    以上是生活随笔為你收集整理的第61篇 笔记-Go 基础的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    狠狠噜狠狠狠狠丁香五月 | 国产真实乱对白精彩久久 | 日韩无码专区 | 岛国片人妻三上悠亚 | 福利一区二区三区视频在线观看 | 日韩精品无码一区二区中文字幕 | 国产真人无遮挡作爱免费视频 | 一本大道伊人av久久综合 | 亚洲中文字幕成人无码 | 日本大香伊一区二区三区 | 国产成人av免费观看 | 人人妻人人藻人人爽欧美一区 | 无码人妻久久一区二区三区不卡 | 亚洲精品无码人妻无码 | 激情内射日本一区二区三区 | 福利一区二区三区视频在线观看 | 双乳奶水饱满少妇呻吟 | 女高中生第一次破苞av | 国产精品久久精品三级 | 少妇性l交大片欧洲热妇乱xxx | 亚洲精品久久久久中文第一幕 | 久久精品无码一区二区三区 | 欧美日韩一区二区综合 | 学生妹亚洲一区二区 | 成人试看120秒体验区 | 中文久久乱码一区二区 | 18精品久久久无码午夜福利 | 狠狠躁日日躁夜夜躁2020 | 国产办公室秘书无码精品99 | 精品国产青草久久久久福利 | 在线a亚洲视频播放在线观看 | 扒开双腿疯狂进出爽爽爽视频 | 男人扒开女人内裤强吻桶进去 | 久久久久成人精品免费播放动漫 | 日本熟妇大屁股人妻 | 日本乱人伦片中文三区 | 亚洲欧美综合区丁香五月小说 | 欧美成人午夜精品久久久 | 免费无码av一区二区 | 成 人 免费观看网站 | 色一情一乱一伦一视频免费看 | 欧美熟妇另类久久久久久不卡 | 久久综合给合久久狠狠狠97色 | 麻豆果冻传媒2021精品传媒一区下载 | 亚洲成av人影院在线观看 | 无码播放一区二区三区 | 无码人妻精品一区二区三区不卡 | 天堂а√在线地址中文在线 | 2019午夜福利不卡片在线 | 亚洲一区二区三区在线观看网站 | a在线观看免费网站大全 | 漂亮人妻洗澡被公强 日日躁 | 强辱丰满人妻hd中文字幕 | 亚洲欧美色中文字幕在线 | 亚洲男人av香蕉爽爽爽爽 | 清纯唯美经典一区二区 | 狠狠综合久久久久综合网 | 国产精品久久精品三级 | 久久久久久a亚洲欧洲av冫 | 精品午夜福利在线观看 | 少妇人妻av毛片在线看 | 亚洲成av人影院在线观看 | 999久久久国产精品消防器材 | 高清无码午夜福利视频 | 妺妺窝人体色www婷婷 | 99久久精品国产一区二区蜜芽 | 无遮挡啪啪摇乳动态图 | 国产精品久久精品三级 | 免费看少妇作爱视频 | 日本大乳高潮视频在线观看 | 久久久精品456亚洲影院 | 国产精品内射视频免费 | 久久97精品久久久久久久不卡 | 欧美日韩在线亚洲综合国产人 | 国产精品18久久久久久麻辣 | 免费人成网站视频在线观看 | 亚洲成av人在线观看网址 | 国产精品久久久久久无码 | 久久精品国产亚洲精品 | 婷婷丁香五月天综合东京热 | 国产精品第一区揄拍无码 | 亚洲精品国偷拍自产在线观看蜜桃 | 正在播放老肥熟妇露脸 | 人人爽人人澡人人人妻 | 内射爽无广熟女亚洲 | 久久99久久99精品中文字幕 | 国产精品久久久久无码av色戒 | 久久人人爽人人爽人人片av高清 | 丰满少妇弄高潮了www | 狂野欧美性猛xxxx乱大交 | 亚洲精品一区二区三区在线观看 | 97无码免费人妻超级碰碰夜夜 | 日韩av无码一区二区三区 | 国产无遮挡又黄又爽免费视频 | 国产成人精品一区二区在线小狼 | 亚洲人成无码网www | 中文字幕乱码中文乱码51精品 | 中文无码伦av中文字幕 | 国产精品沙发午睡系列 | 综合激情五月综合激情五月激情1 | 在线观看国产一区二区三区 | 天天摸天天碰天天添 | 澳门永久av免费网站 | 夜先锋av资源网站 | 亚洲日韩av一区二区三区中文 | 国产精品理论片在线观看 | 国产精品无码永久免费888 | 熟妇人妻激情偷爽文 | 日本在线高清不卡免费播放 | 熟妇人妻无乱码中文字幕 | 国产精品成人av在线观看 | 国产精品久久福利网站 | 少妇高潮一区二区三区99 | 国产精品美女久久久久av爽李琼 | 天堂а√在线地址中文在线 | 欧美 日韩 人妻 高清 中文 | 国内精品久久毛片一区二区 | 日本丰满护士爆乳xxxx | 天天拍夜夜添久久精品大 | 国产精品久免费的黄网站 | 欧美日韩一区二区三区自拍 | 欧美精品国产综合久久 | 欧美zoozzooz性欧美 | 久久久久亚洲精品男人的天堂 | 国产婷婷色一区二区三区在线 | 狠狠cao日日穞夜夜穞av | 亚洲人成网站在线播放942 | 白嫩日本少妇做爰 | 日韩成人一区二区三区在线观看 | 欧美人与禽zoz0性伦交 | 精品一区二区三区无码免费视频 | 国产在线精品一区二区三区直播 | 无码精品国产va在线观看dvd | 一本久道久久综合婷婷五月 | 免费看少妇作爱视频 | 国产精品嫩草久久久久 | 中文精品久久久久人妻不卡 | 黑森林福利视频导航 | 久久婷婷五月综合色国产香蕉 | 1000部夫妻午夜免费 | 精品国产国产综合精品 | 成年美女黄网站色大免费全看 | 亚洲精品久久久久avwww潮水 | 国产欧美熟妇另类久久久 | 丝袜足控一区二区三区 | 国产舌乚八伦偷品w中 | 色婷婷香蕉在线一区二区 | 中文无码伦av中文字幕 | 国产精品毛多多水多 | 玩弄人妻少妇500系列视频 | 少妇无码一区二区二三区 | 男人扒开女人内裤强吻桶进去 | 久久综合狠狠综合久久综合88 | 狠狠色欧美亚洲狠狠色www | 亚洲午夜福利在线观看 | 中文字幕中文有码在线 | 女人被爽到呻吟gif动态图视看 | 国产无遮挡又黄又爽又色 | 双乳奶水饱满少妇呻吟 | 日本一本二本三区免费 | 在线精品国产一区二区三区 | 日本肉体xxxx裸交 | 夜精品a片一区二区三区无码白浆 | 一本大道久久东京热无码av | 无码人妻久久一区二区三区不卡 | 亚洲精品综合五月久久小说 | 国产精品丝袜黑色高跟鞋 | 国产av剧情md精品麻豆 | 亚洲精品中文字幕久久久久 | 麻豆国产丝袜白领秘书在线观看 | 色偷偷人人澡人人爽人人模 | 夫妻免费无码v看片 | 无遮挡国产高潮视频免费观看 | 成人影院yy111111在线观看 | 久久99精品国产.久久久久 | 精品 日韩 国产 欧美 视频 | 亚洲 a v无 码免 费 成 人 a v | 成人动漫在线观看 | 97夜夜澡人人爽人人喊中国片 | 97无码免费人妻超级碰碰夜夜 | 亚洲综合色区中文字幕 | 亚洲午夜福利在线观看 | 少妇的肉体aa片免费 | 嫩b人妻精品一区二区三区 | 人人爽人人澡人人高潮 | 又粗又大又硬又长又爽 | 玩弄少妇高潮ⅹxxxyw | 国内精品人妻无码久久久影院蜜桃 | 精品国精品国产自在久国产87 | 中文字幕人妻无码一区二区三区 | аⅴ资源天堂资源库在线 | 亚洲国产欧美国产综合一区 | 性欧美牲交在线视频 | 台湾无码一区二区 | 欧美激情内射喷水高潮 | 亚洲一区二区三区四区 | 性生交大片免费看l | 免费无码av一区二区 | 亚洲一区二区观看播放 | 精品国产一区二区三区av 性色 | 久久www免费人成人片 | 一本精品99久久精品77 | 精品国产一区二区三区av 性色 | 欧美大屁股xxxxhd黑色 | 日日摸日日碰夜夜爽av | 精品水蜜桃久久久久久久 | 欧美一区二区三区视频在线观看 | 99精品国产综合久久久久五月天 | 欧美精品一区二区精品久久 | 全球成人中文在线 | 国产精品无套呻吟在线 | 中文字幕av无码一区二区三区电影 | 奇米影视7777久久精品人人爽 | 国产精品久久久久久亚洲影视内衣 | 国产精品亚洲а∨无码播放麻豆 | 日韩少妇白浆无码系列 | 国产做国产爱免费视频 | 影音先锋中文字幕无码 | 亚洲精品国偷拍自产在线观看蜜桃 | 国产精品自产拍在线观看 | 女人被爽到呻吟gif动态图视看 | 国产午夜视频在线观看 | 全黄性性激高免费视频 | 国产精品亚洲а∨无码播放麻豆 | 色综合久久88色综合天天 | 天天综合网天天综合色 | 精品国产精品久久一区免费式 | 丝袜足控一区二区三区 | 最近的中文字幕在线看视频 | 久久久中文久久久无码 | 精品一区二区不卡无码av | 久久久久99精品成人片 | 婷婷综合久久中文字幕蜜桃三电影 | 大地资源网第二页免费观看 | 久久99精品久久久久婷婷 | 色一情一乱一伦 | 少妇性l交大片 | 粉嫩少妇内射浓精videos | 欧美成人高清在线播放 | 欧美日本免费一区二区三区 | 欧美日本精品一区二区三区 | 日韩精品无码一本二本三本色 | 欧美老妇与禽交 | 国产欧美熟妇另类久久久 | 久久国内精品自在自线 | 国产人妻精品一区二区三区 | 亚洲中文无码av永久不收费 | 精品一区二区三区波多野结衣 | 国产人妻精品一区二区三区不卡 | 日本精品少妇一区二区三区 | 麻花豆传媒剧国产免费mv在线 | 国产九九九九九九九a片 | 久久这里只有精品视频9 | 久久99精品国产麻豆蜜芽 | 伊人久久婷婷五月综合97色 | 国产乱码精品一品二品 | 波多野结衣高清一区二区三区 | 色婷婷综合激情综在线播放 | 成人影院yy111111在线观看 | 国产99久久精品一区二区 | 日韩av无码中文无码电影 | 成人免费视频在线观看 | 国产精品久久久久久亚洲毛片 | 亚洲色在线无码国产精品不卡 | 精品午夜福利在线观看 | 亚洲精品国产精品乱码不卡 | 精品久久久久香蕉网 | yw尤物av无码国产在线观看 | 中文久久乱码一区二区 | 亚洲日本在线电影 | 亚洲中文字幕乱码av波多ji | 99国产精品白浆在线观看免费 | 成熟人妻av无码专区 | 精品无人国产偷自产在线 | 精品久久8x国产免费观看 | 漂亮人妻洗澡被公强 日日躁 | 无码人妻久久一区二区三区不卡 | 377p欧洲日本亚洲大胆 | 国产精品久久久久9999小说 | 婷婷五月综合缴情在线视频 | 少妇无码一区二区二三区 | 无码人妻丰满熟妇区五十路百度 | 一个人看的www免费视频在线观看 | 国产艳妇av在线观看果冻传媒 | 狂野欧美性猛交免费视频 | 国产激情无码一区二区 | 99久久亚洲精品无码毛片 | 成熟女人特级毛片www免费 | 色欲综合久久中文字幕网 | 国产激情综合五月久久 | 国产成人无码av片在线观看不卡 | 免费看男女做好爽好硬视频 | 老熟女乱子伦 | 国内精品人妻无码久久久影院蜜桃 | 久久久久免费精品国产 | 亚洲日本在线电影 | 亚洲国产精品一区二区美利坚 | 骚片av蜜桃精品一区 | 人人爽人人爽人人片av亚洲 | 兔费看少妇性l交大片免费 | 黑森林福利视频导航 | 日本在线高清不卡免费播放 | www国产亚洲精品久久久日本 | 无码免费一区二区三区 | 亚洲国产精品久久人人爱 | 国产凸凹视频一区二区 | 成年美女黄网站色大免费视频 | 一本大道伊人av久久综合 | 日本精品久久久久中文字幕 | 狠狠噜狠狠狠狠丁香五月 | 国产真实伦对白全集 | 亚洲成av人片在线观看无码不卡 | 一本久久a久久精品亚洲 | 天天摸天天碰天天添 | 又紧又大又爽精品一区二区 | 人人妻人人藻人人爽欧美一区 | 亚洲另类伦春色综合小说 | 色综合久久88色综合天天 | 亚洲日韩av一区二区三区中文 | 国产成人精品一区二区在线小狼 | 一区二区传媒有限公司 | 亚洲狠狠婷婷综合久久 | 久久国产精品二国产精品 | 青春草在线视频免费观看 | 欧美日韩视频无码一区二区三 | 男女作爱免费网站 | 久久精品人妻少妇一区二区三区 | 97se亚洲精品一区 | 亚洲国产成人a精品不卡在线 | 狠狠色噜噜狠狠狠7777奇米 | 色婷婷综合激情综在线播放 | 98国产精品综合一区二区三区 | 在线欧美精品一区二区三区 | 久久精品人人做人人综合试看 | 国产av一区二区精品久久凹凸 | 精品水蜜桃久久久久久久 | 亚洲精品久久久久久久久久久 | 国产福利视频一区二区 | 亚洲小说图区综合在线 | 亚洲 a v无 码免 费 成 人 a v | 亚洲欧美国产精品专区久久 | 欧美freesex黑人又粗又大 | 中文无码精品a∨在线观看不卡 | 久久综合九色综合97网 | 中文字幕色婷婷在线视频 | 欧美性生交xxxxx久久久 | 国产超级va在线观看视频 | 台湾无码一区二区 | 国产农村乱对白刺激视频 | 熟妇女人妻丰满少妇中文字幕 | 国产乱人偷精品人妻a片 | 色综合久久中文娱乐网 | 无码人妻精品一区二区三区不卡 | 日韩欧美成人免费观看 | 欧美日韩亚洲国产精品 | 国产真实乱对白精彩久久 | 亚洲精品久久久久中文第一幕 | 99久久人妻精品免费二区 | 精品国产一区av天美传媒 | av无码电影一区二区三区 | 欧美一区二区三区 | 国产免费久久精品国产传媒 | 丰满肥臀大屁股熟妇激情视频 | 国产精品多人p群无码 | 国产精品毛多多水多 | 一本大道久久东京热无码av | 久久久久亚洲精品中文字幕 | 日日橹狠狠爱欧美视频 | 在线看片无码永久免费视频 | 中文字幕乱码人妻无码久久 | 中文字幕无码人妻少妇免费 | 国产精品亚洲专区无码不卡 | 在线播放无码字幕亚洲 | 国产精品a成v人在线播放 | 98国产精品综合一区二区三区 | 亚洲成在人网站无码天堂 | 亚洲综合精品香蕉久久网 | 中文精品久久久久人妻不卡 | 色 综合 欧美 亚洲 国产 | 无码人妻少妇伦在线电影 | 色婷婷欧美在线播放内射 | 精品一区二区三区波多野结衣 | 久久熟妇人妻午夜寂寞影院 | 亚洲精品成人福利网站 | 无码人中文字幕 | 帮老师解开蕾丝奶罩吸乳网站 | 国产亚洲精品久久久久久国模美 | 黑人粗大猛烈进出高潮视频 | 亚洲aⅴ无码成人网站国产app | 色情久久久av熟女人妻网站 | 亚洲综合久久一区二区 | 亚洲区欧美区综合区自拍区 | 久在线观看福利视频 | 亚洲欧洲日本无在线码 | 欧美日韩综合一区二区三区 | 99精品视频在线观看免费 | 乱码午夜-极国产极内射 | 人妻少妇精品无码专区动漫 | 日韩精品成人一区二区三区 | 装睡被陌生人摸出水好爽 | 久久久无码中文字幕久... | 国产 浪潮av性色四虎 | 中文无码精品a∨在线观看不卡 | 狠狠cao日日穞夜夜穞av | 亚洲精品久久久久avwww潮水 | 久久久久99精品国产片 | 久久久精品欧美一区二区免费 | 国产特级毛片aaaaaa高潮流水 | 东京无码熟妇人妻av在线网址 | 狠狠色丁香久久婷婷综合五月 | 久精品国产欧美亚洲色aⅴ大片 | 综合网日日天干夜夜久久 | 久久午夜夜伦鲁鲁片无码免费 | 波多野结衣一区二区三区av免费 | 久久99精品国产.久久久久 | 日韩欧美成人免费观看 | 国产性生交xxxxx无码 | 成人无码精品1区2区3区免费看 | aⅴ亚洲 日韩 色 图网站 播放 | 免费国产成人高清在线观看网站 | 欧美日本精品一区二区三区 | 国产精品美女久久久网av | 黑森林福利视频导航 | 女人被爽到呻吟gif动态图视看 | 免费视频欧美无人区码 | 青青久在线视频免费观看 | 国产97人人超碰caoprom | 黑人大群体交免费视频 | 黑人巨大精品欧美黑寡妇 | 日日干夜夜干 | 十八禁真人啪啪免费网站 | 黑人大群体交免费视频 | 久久久精品456亚洲影院 | 76少妇精品导航 | 98国产精品综合一区二区三区 | 国产成人av免费观看 | 久久久国产精品无码免费专区 | 在线a亚洲视频播放在线观看 | 在线观看欧美一区二区三区 | 最近的中文字幕在线看视频 | 中文亚洲成a人片在线观看 | 亚洲乱码中文字幕在线 | 亚洲啪av永久无码精品放毛片 | 综合激情五月综合激情五月激情1 | 婷婷综合久久中文字幕蜜桃三电影 | 精品人妻人人做人人爽夜夜爽 | 亚洲欧美日韩国产精品一区二区 | 久久精品人妻少妇一区二区三区 | 女人被爽到呻吟gif动态图视看 | 日日躁夜夜躁狠狠躁 | 永久免费观看国产裸体美女 | 亚洲国产av精品一区二区蜜芽 | 国产免费久久久久久无码 | 日本欧美一区二区三区乱码 | 国产午夜手机精彩视频 | 国产无av码在线观看 | 又湿又紧又大又爽a视频国产 | 美女毛片一区二区三区四区 | 精品少妇爆乳无码av无码专区 | 亚洲午夜福利在线观看 | 漂亮人妻洗澡被公强 日日躁 | 男女超爽视频免费播放 | 丰腴饱满的极品熟妇 | 自拍偷自拍亚洲精品被多人伦好爽 | 欧美精品国产综合久久 | 欧美野外疯狂做受xxxx高潮 | 欧美日本日韩 | 国产一区二区三区精品视频 | 水蜜桃色314在线观看 | 国产精品毛多多水多 | 夜夜影院未满十八勿进 | 18禁止看的免费污网站 | 老熟妇乱子伦牲交视频 | 97久久精品无码一区二区 | 欧美日韩色另类综合 | 性开放的女人aaa片 | 一本色道婷婷久久欧美 | 岛国片人妻三上悠亚 | 国产精品理论片在线观看 | 欧美丰满熟妇xxxx | 精品无人区无码乱码毛片国产 | 欧美三级不卡在线观看 | 少妇人妻av毛片在线看 | 亚洲 a v无 码免 费 成 人 a v | 久久99国产综合精品 | 天天做天天爱天天爽综合网 | 一二三四社区在线中文视频 | 亚洲熟悉妇女xxx妇女av | 丝袜足控一区二区三区 | 国产成人午夜福利在线播放 | 免费无码肉片在线观看 | 人人妻人人澡人人爽人人精品浪潮 | 亚洲日韩一区二区 | 久久久国产一区二区三区 | 国产又爽又黄又刺激的视频 | 男女爱爱好爽视频免费看 | 亚洲日韩乱码中文无码蜜桃臀网站 | 精品无人国产偷自产在线 | 自拍偷自拍亚洲精品被多人伦好爽 | 熟妇女人妻丰满少妇中文字幕 | 久久综合给久久狠狠97色 | 夜夜躁日日躁狠狠久久av | 天堂久久天堂av色综合 | 97精品国产97久久久久久免费 | 亚洲熟妇色xxxxx欧美老妇y | 国产成人人人97超碰超爽8 | 久久伊人色av天堂九九小黄鸭 | 国产一精品一av一免费 | 久久精品人人做人人综合 | 亚洲の无码国产の无码影院 | 精品人妻人人做人人爽夜夜爽 | 东京热男人av天堂 | 亚洲国产精品无码久久久久高潮 | 久久国产自偷自偷免费一区调 | 欧洲vodafone精品性 | 永久免费观看美女裸体的网站 | 欧美野外疯狂做受xxxx高潮 | 国产激情精品一区二区三区 | av在线亚洲欧洲日产一区二区 | 中文字幕日韩精品一区二区三区 | a在线观看免费网站大全 | 国产精品怡红院永久免费 | 国产特级毛片aaaaaaa高清 | 亚洲小说图区综合在线 | 亚洲国产av精品一区二区蜜芽 | 日本大香伊一区二区三区 | 久久久久久久女国产乱让韩 | 国产电影无码午夜在线播放 | 粉嫩少妇内射浓精videos | 99久久99久久免费精品蜜桃 | 国产成人精品久久亚洲高清不卡 | 久久综合久久自在自线精品自 | 蜜臀av无码人妻精品 | 亚洲自偷自偷在线制服 | 国产精品久久久一区二区三区 | 国产97在线 | 亚洲 | 99久久精品无码一区二区毛片 | 久久天天躁夜夜躁狠狠 | 丰满肥臀大屁股熟妇激情视频 | 久久精品人人做人人综合试看 | 一二三四在线观看免费视频 | 婷婷五月综合缴情在线视频 | 无套内谢的新婚少妇国语播放 | 欧美肥老太牲交大战 | 嫩b人妻精品一区二区三区 | 免费播放一区二区三区 | 亚洲欧美色中文字幕在线 | 午夜丰满少妇性开放视频 | 丰腴饱满的极品熟妇 | 成在人线av无码免观看麻豆 | 国产精品资源一区二区 | 久久亚洲精品成人无码 | 久久www免费人成人片 | 性欧美熟妇videofreesex | 午夜福利不卡在线视频 | 无码人妻精品一区二区三区不卡 | 久9re热视频这里只有精品 | 欧美日韩一区二区免费视频 | 精品厕所偷拍各类美女tp嘘嘘 | 国产成人综合美国十次 | 丝袜人妻一区二区三区 | 樱花草在线播放免费中文 | 无码人妻少妇伦在线电影 | 欧美人与动性行为视频 | 全黄性性激高免费视频 | 欧美国产亚洲日韩在线二区 | 国产特级毛片aaaaaaa高清 | 色一情一乱一伦一区二区三欧美 | 一二三四在线观看免费视频 | 性色av无码免费一区二区三区 | 国产人妻人伦精品 | 国产精品人妻一区二区三区四 | av无码久久久久不卡免费网站 | 亚洲成色在线综合网站 | 无码av免费一区二区三区试看 | 精品无码一区二区三区的天堂 | 在线观看国产一区二区三区 | 激情内射亚州一区二区三区爱妻 | 亚洲午夜无码久久 | 国产在热线精品视频 | 日本肉体xxxx裸交 | 久久综合狠狠综合久久综合88 | 在线欧美精品一区二区三区 | 蜜桃视频插满18在线观看 | 色窝窝无码一区二区三区色欲 | 东京热无码av男人的天堂 | 欧美 日韩 人妻 高清 中文 | 好男人社区资源 | 国产三级久久久精品麻豆三级 | 亚洲中文字幕无码一久久区 | 国产特级毛片aaaaaa高潮流水 | 青草青草久热国产精品 | 大地资源中文第3页 | 东京一本一道一二三区 | 亚洲色欲久久久综合网东京热 | 精品国精品国产自在久国产87 | 亚洲色欲色欲天天天www | 亚洲色偷偷偷综合网 | 18精品久久久无码午夜福利 | 香港三级日本三级妇三级 | 少妇一晚三次一区二区三区 | 亚洲精品久久久久中文第一幕 | 日本精品久久久久中文字幕 | 国产精品毛多多水多 | 国内揄拍国内精品人妻 | 在线精品亚洲一区二区 | 国产精品无码永久免费888 | 国产色视频一区二区三区 | 网友自拍区视频精品 | 久久精品国产精品国产精品污 | 免费中文字幕日韩欧美 | 色欲人妻aaaaaaa无码 | 免费看男女做好爽好硬视频 | 午夜成人1000部免费视频 | 亚洲s码欧洲m码国产av | 女高中生第一次破苞av | 女高中生第一次破苞av | 日本熟妇大屁股人妻 | 国产成人无码av在线影院 | 欧美性生交活xxxxxdddd | 国产超碰人人爽人人做人人添 | 国产亚洲精品久久久久久久 | 欧美成人午夜精品久久久 | 日本xxxx色视频在线观看免费 | 激情国产av做激情国产爱 | 成 人 网 站国产免费观看 | 一区二区三区乱码在线 | 欧洲 | 在线а√天堂中文官网 | 男人扒开女人内裤强吻桶进去 | 日本精品人妻无码免费大全 | 久久久久亚洲精品男人的天堂 | 少妇人妻偷人精品无码视频 | 波多野结衣一区二区三区av免费 | 中文字幕人妻无码一夲道 | 一区二区传媒有限公司 | 99久久精品国产一区二区蜜芽 | 国产肉丝袜在线观看 | 亚洲毛片av日韩av无码 | 国产亚洲tv在线观看 | 日本一区二区三区免费高清 | 日日天干夜夜狠狠爱 | 97精品国产97久久久久久免费 | 日本一卡二卡不卡视频查询 | 欧美激情综合亚洲一二区 | 久久久久久久久蜜桃 | 亚洲区欧美区综合区自拍区 | 亚洲精品国产精品乱码不卡 | 国产精品久久久久影院嫩草 | 国产精品免费大片 | 熟女体下毛毛黑森林 | 毛片内射-百度 | 蜜桃av抽搐高潮一区二区 | 婷婷色婷婷开心五月四房播播 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 久久久成人毛片无码 | 亚洲一区二区三区偷拍女厕 | 无码人妻久久一区二区三区不卡 | 2020久久香蕉国产线看观看 | 久久久久免费看成人影片 | 永久免费观看国产裸体美女 | 青春草在线视频免费观看 | 麻豆精品国产精华精华液好用吗 | 97夜夜澡人人爽人人喊中国片 | 亚洲日本va午夜在线电影 | 一本无码人妻在中文字幕免费 | 国产亚洲精品久久久闺蜜 | 欧美人与禽猛交狂配 | 亚洲高清偷拍一区二区三区 | 国产精品丝袜黑色高跟鞋 | 亚洲精品国产精品乱码不卡 | 精品水蜜桃久久久久久久 | 亚欧洲精品在线视频免费观看 | 一个人看的视频www在线 | 精品国产精品久久一区免费式 | 欧美日本免费一区二区三区 | 成人女人看片免费视频放人 | 麻花豆传媒剧国产免费mv在线 | 国产综合久久久久鬼色 | 99er热精品视频 | 日本肉体xxxx裸交 | 九月婷婷人人澡人人添人人爽 | 双乳奶水饱满少妇呻吟 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 曰本女人与公拘交酡免费视频 | 国产性生交xxxxx无码 | 人妻少妇精品久久 | 人人爽人人爽人人片av亚洲 | 巨爆乳无码视频在线观看 | 国内精品一区二区三区不卡 | 国产精品久久久av久久久 | 国产午夜亚洲精品不卡 | 亚洲综合在线一区二区三区 | 成年女人永久免费看片 | √天堂资源地址中文在线 | 成人无码视频在线观看网站 | 欧美人与禽zoz0性伦交 | 久久久无码中文字幕久... | 婷婷六月久久综合丁香 | 久久精品一区二区三区四区 | 国产精品永久免费视频 | 少妇性l交大片欧洲热妇乱xxx | 中文字幕无线码 | 77777熟女视频在线观看 а天堂中文在线官网 | 女人被男人躁得好爽免费视频 | 亚洲人成无码网www | 撕开奶罩揉吮奶头视频 | 亚洲 高清 成人 动漫 | 丰满妇女强制高潮18xxxx | 国内揄拍国内精品人妻 | 日本精品少妇一区二区三区 | 人人妻人人澡人人爽精品欧美 | 久久国产精品偷任你爽任你 | 人妻aⅴ无码一区二区三区 | 97人妻精品一区二区三区 | 亚洲人成网站免费播放 | 色综合久久中文娱乐网 | 亚洲国产av精品一区二区蜜芽 | 久久久精品欧美一区二区免费 | 一本久久a久久精品vr综合 | 日日摸天天摸爽爽狠狠97 | 亚洲国产欧美在线成人 | 亚洲精品久久久久久一区二区 | 小鲜肉自慰网站xnxx | 国产精品.xx视频.xxtv | 国产尤物精品视频 | 漂亮人妻洗澡被公强 日日躁 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 内射爽无广熟女亚洲 | 激情国产av做激情国产爱 | 麻豆国产丝袜白领秘书在线观看 | 日本乱偷人妻中文字幕 | 色偷偷人人澡人人爽人人模 | 亚洲一区二区三区含羞草 | 中国大陆精品视频xxxx | 人人妻人人藻人人爽欧美一区 | 亚洲国产精品一区二区美利坚 | 亚洲色欲色欲欲www在线 | 亚洲国产精品一区二区美利坚 | 精品亚洲成av人在线观看 | 老太婆性杂交欧美肥老太 | 亚洲精品国偷拍自产在线观看蜜桃 | 中文字幕+乱码+中文字幕一区 | 久久久www成人免费毛片 | 奇米影视7777久久精品 | 日日摸天天摸爽爽狠狠97 | 日韩少妇内射免费播放 | 夜夜高潮次次欢爽av女 | 精品偷拍一区二区三区在线看 | 男女猛烈xx00免费视频试看 | 丝袜 中出 制服 人妻 美腿 | 久久精品国产日本波多野结衣 | 中文精品久久久久人妻不卡 | 精品国产青草久久久久福利 | 亚洲日韩中文字幕在线播放 | 亚洲爆乳精品无码一区二区三区 | 成人无码影片精品久久久 | 乱人伦人妻中文字幕无码久久网 | 亚洲s码欧洲m码国产av | 久久久精品欧美一区二区免费 | av无码不卡在线观看免费 | 国产午夜精品一区二区三区嫩草 | 精品水蜜桃久久久久久久 | 强辱丰满人妻hd中文字幕 | 大地资源网第二页免费观看 | 精品人人妻人人澡人人爽人人 | 在线观看国产一区二区三区 | 久久综合给久久狠狠97色 | 亚洲 a v无 码免 费 成 人 a v | 小泽玛莉亚一区二区视频在线 | 亚洲无人区一区二区三区 | 精品无码国产自产拍在线观看蜜 | 精品成人av一区二区三区 | 中文字幕+乱码+中文字幕一区 | 天天综合网天天综合色 | 欧美精品免费观看二区 | 在线天堂新版最新版在线8 | 国产香蕉尹人综合在线观看 | 国语自产偷拍精品视频偷 | 日本护士xxxxhd少妇 | 未满小14洗澡无码视频网站 | 樱花草在线社区www | 久久精品女人天堂av免费观看 | 东京无码熟妇人妻av在线网址 | 亚洲人成影院在线无码按摩店 | 欧美黑人巨大xxxxx | 黑人粗大猛烈进出高潮视频 | 亚洲精品久久久久avwww潮水 | 男女爱爱好爽视频免费看 | av无码电影一区二区三区 | 天天做天天爱天天爽综合网 | 少妇厨房愉情理9仑片视频 | 在线a亚洲视频播放在线观看 | 东京热男人av天堂 | 国产乱人无码伦av在线a | 日日碰狠狠躁久久躁蜜桃 | 欧美人与牲动交xxxx | 少妇高潮一区二区三区99 | 欧美性猛交内射兽交老熟妇 | 99精品久久毛片a片 | 亚洲 另类 在线 欧美 制服 | 亚洲色欲色欲天天天www | 大色综合色综合网站 | 中文无码成人免费视频在线观看 | 一本色道久久综合亚洲精品不卡 | а√天堂www在线天堂小说 | 1000部啪啪未满十八勿入下载 | 久久午夜夜伦鲁鲁片无码免费 | 国内老熟妇对白xxxxhd | 国产一精品一av一免费 | 欧美变态另类xxxx | 激情国产av做激情国产爱 | 日本高清一区免费中文视频 | 天海翼激烈高潮到腰振不止 | 无码国内精品人妻少妇 | 少女韩国电视剧在线观看完整 | 国产成人一区二区三区别 | 亚洲啪av永久无码精品放毛片 | 老熟妇仑乱视频一区二区 | 亚洲色欲色欲天天天www | 99riav国产精品视频 | 少妇高潮一区二区三区99 | 国产办公室秘书无码精品99 | 377p欧洲日本亚洲大胆 | 国产精华av午夜在线观看 | 香蕉久久久久久av成人 | 久青草影院在线观看国产 | 亚洲精品国偷拍自产在线麻豆 | 荫蒂被男人添的好舒服爽免费视频 | 国产深夜福利视频在线 | 日韩欧美成人免费观看 | 欧美人妻一区二区三区 | 无码国产色欲xxxxx视频 | 中文字幕乱码人妻二区三区 | 国产 浪潮av性色四虎 | 亚洲色偷偷男人的天堂 | 欧美国产日韩久久mv | 熟女体下毛毛黑森林 | 国产午夜无码视频在线观看 | 国精品人妻无码一区二区三区蜜柚 | 女高中生第一次破苞av | 久久久精品456亚洲影院 | 亚洲精品一区二区三区大桥未久 | 久9re热视频这里只有精品 | 国产精品久久久av久久久 | 男女爱爱好爽视频免费看 | 国产av无码专区亚洲awww | 国产一区二区三区精品视频 | 久久久久av无码免费网 | 国产偷抇久久精品a片69 | 亚洲精品一区三区三区在线观看 | 男人的天堂av网站 | 亚洲s色大片在线观看 | 小泽玛莉亚一区二区视频在线 | 久久精品国产日本波多野结衣 | 国产人妻久久精品二区三区老狼 | 国产凸凹视频一区二区 | 成人无码视频免费播放 | 国产成人精品无码播放 | 久久国产精品偷任你爽任你 | 亚洲aⅴ无码成人网站国产app | 天天综合网天天综合色 | 人妻少妇精品无码专区动漫 | 一二三四在线观看免费视频 | 婷婷丁香六月激情综合啪 | 一个人免费观看的www视频 | 国精产品一品二品国精品69xx | 男女下面进入的视频免费午夜 | 中文字幕无码人妻少妇免费 | 日本大香伊一区二区三区 | 牲欲强的熟妇农村老妇女视频 | 亚洲成色www久久网站 | 无码人妻精品一区二区三区不卡 | 日本熟妇人妻xxxxx人hd | 99国产精品白浆在线观看免费 | 2019午夜福利不卡片在线 | 久久久久久久女国产乱让韩 | 中文字幕无码乱人伦 | 国产精品成人av在线观看 | 特大黑人娇小亚洲女 | 精品国产一区二区三区四区 | 强奷人妻日本中文字幕 | 亚洲成色在线综合网站 | 老子影院午夜精品无码 | 曰韩无码二三区中文字幕 | 欧美人与禽zoz0性伦交 | 性色欲网站人妻丰满中文久久不卡 | 欧美喷潮久久久xxxxx | 天天躁日日躁狠狠躁免费麻豆 | www一区二区www免费 | 亚洲成a人片在线观看无码3d | 久久久久久久女国产乱让韩 | √天堂中文官网8在线 | 久久无码专区国产精品s | 欧美成人免费全部网站 | 欧洲极品少妇 | 亚洲a无码综合a国产av中文 | 欧美人与动性行为视频 | 成人无码精品1区2区3区免费看 | 欧美国产亚洲日韩在线二区 | 国产偷国产偷精品高清尤物 | 一本无码人妻在中文字幕免费 | 久久综合给合久久狠狠狠97色 | 免费乱码人妻系列无码专区 | 国产无套粉嫩白浆在线 | 在线播放免费人成毛片乱码 | 欧美怡红院免费全部视频 | a在线观看免费网站大全 | 国产女主播喷水视频在线观看 | 亚洲天堂2017无码 | 亚洲国产欧美日韩精品一区二区三区 | 色狠狠av一区二区三区 | 亚洲aⅴ无码成人网站国产app | 精品人人妻人人澡人人爽人人 | 天天拍夜夜添久久精品大 | 国产精品久久久一区二区三区 | 福利一区二区三区视频在线观看 | www成人国产高清内射 | 人妻体内射精一区二区三四 | 亚洲精品一区二区三区大桥未久 | 国产在线一区二区三区四区五区 | 亚洲综合无码一区二区三区 | 性色欲网站人妻丰满中文久久不卡 | 免费国产成人高清在线观看网站 | 成人av无码一区二区三区 | 亚洲第一网站男人都懂 | 国产av一区二区精品久久凹凸 | 亚洲午夜福利在线观看 | 亚洲经典千人经典日产 | 亚洲另类伦春色综合小说 | 国产一区二区三区四区五区加勒比 | 国产成人综合在线女婷五月99播放 | 亚洲成熟女人毛毛耸耸多 | 野狼第一精品社区 | 九一九色国产 | 色综合久久久无码网中文 | 男人扒开女人内裤强吻桶进去 | 日本精品高清一区二区 | 无码福利日韩神码福利片 | 日本高清一区免费中文视频 | 亚洲成a人片在线观看日本 | 国产精品美女久久久久av爽李琼 | 久久久亚洲欧洲日产国码αv | 亚洲色成人中文字幕网站 | 国产成人亚洲综合无码 | 成在人线av无码免观看麻豆 | 日本精品久久久久中文字幕 | 天天做天天爱天天爽综合网 | 人妻少妇精品无码专区动漫 | 成 人 网 站国产免费观看 | 少妇性荡欲午夜性开放视频剧场 | 成人动漫在线观看 | 午夜免费福利小电影 | 一本无码人妻在中文字幕免费 | 偷窥日本少妇撒尿chinese | 波多野结衣一区二区三区av免费 | 久久99精品国产麻豆蜜芽 | 高中生自慰www网站 | 精品偷拍一区二区三区在线看 | 成年女人永久免费看片 | 黑森林福利视频导航 | 中文字幕日韩精品一区二区三区 | 国产精品成人av在线观看 | 国产成人精品无码播放 | 久久国语露脸国产精品电影 | 无码av中文字幕免费放 | 三上悠亚人妻中文字幕在线 | 亚洲一区二区三区国产精华液 | 久久精品无码一区二区三区 | 亚洲人成网站免费播放 | 免费看男女做好爽好硬视频 | 亚洲欧美色中文字幕在线 | 亚洲理论电影在线观看 | 小泽玛莉亚一区二区视频在线 | 伊在人天堂亚洲香蕉精品区 | 久久久久久a亚洲欧洲av冫 | 国产综合在线观看 | 国精品人妻无码一区二区三区蜜柚 | 国内精品人妻无码久久久影院 | 亚洲无人区一区二区三区 | 夫妻免费无码v看片 | 波多野结衣一区二区三区av免费 | 蜜桃视频韩日免费播放 | 乱人伦人妻中文字幕无码久久网 | 国产成人无码一二三区视频 | 一本久久a久久精品vr综合 | 狠狠色噜噜狠狠狠狠7777米奇 | 伊人久久大香线蕉av一区二区 | 人人爽人人澡人人高潮 | 97夜夜澡人人爽人人喊中国片 | 女人被男人躁得好爽免费视频 | 日韩av无码中文无码电影 | 亚洲国产精品一区二区第一页 | 亚洲の无码国产の无码步美 | 大色综合色综合网站 | 亚洲成av人片在线观看无码不卡 | 国产成人综合美国十次 | 国产午夜视频在线观看 | 国产99久久精品一区二区 | 亚洲中文字幕无码中文字在线 | 未满小14洗澡无码视频网站 | 激情内射亚州一区二区三区爱妻 | 久久99精品国产麻豆 | 300部国产真实乱 | 精品厕所偷拍各类美女tp嘘嘘 | 国内精品久久久久久中文字幕 | 欧美乱妇无乱码大黄a片 | 兔费看少妇性l交大片免费 | 成人影院yy111111在线观看 | √8天堂资源地址中文在线 | 亚洲日本在线电影 | 日韩av无码一区二区三区不卡 | 精品 日韩 国产 欧美 视频 | 老头边吃奶边弄进去呻吟 | 性色av无码免费一区二区三区 | 欧美真人作爱免费视频 | 日日摸天天摸爽爽狠狠97 | 特黄特色大片免费播放器图片 | 男女下面进入的视频免费午夜 | 97久久超碰中文字幕 | 国产高清av在线播放 | 精品国产一区av天美传媒 | 午夜福利不卡在线视频 | 蜜桃av抽搐高潮一区二区 | 秋霞特色aa大片 | 樱花草在线播放免费中文 | 亚洲一区av无码专区在线观看 | 在线播放免费人成毛片乱码 | 国产精品亚洲五月天高清 | 国产精品久久国产精品99 | 四十如虎的丰满熟妇啪啪 | 日韩人妻无码一区二区三区久久99 | 兔费看少妇性l交大片免费 | 久久久精品人妻久久影视 | 久久久久国色av免费观看性色 | 久久这里只有精品视频9 | 国产成人无码区免费内射一片色欲 | 国内精品久久久久久中文字幕 | 日本爽爽爽爽爽爽在线观看免 | 国产午夜精品一区二区三区嫩草 | 久久综合色之久久综合 | 亚洲综合无码一区二区三区 | 国产成人精品视频ⅴa片软件竹菊 | 中文字幕无码免费久久9一区9 | 亚洲精品久久久久中文第一幕 | 一个人看的www免费视频在线观看 | 欧美性黑人极品hd | 正在播放东北夫妻内射 | 狠狠综合久久久久综合网 | 亚洲高清偷拍一区二区三区 | 中文字幕人妻无码一区二区三区 | 美女张开腿让人桶 | 99久久亚洲精品无码毛片 | 国产成人无码a区在线观看视频app | 国内少妇偷人精品视频免费 | 少妇被粗大的猛进出69影院 | 国产免费观看黄av片 | 国产艳妇av在线观看果冻传媒 | 色综合久久88色综合天天 | 久久精品一区二区三区四区 | 久久久国产精品无码免费专区 | 乱人伦中文视频在线观看 | 午夜肉伦伦影院 | 牲欲强的熟妇农村老妇女视频 | 国产97人人超碰caoprom | 97无码免费人妻超级碰碰夜夜 | 亚洲乱亚洲乱妇50p | 久久综合给合久久狠狠狠97色 | 99riav国产精品视频 | 99麻豆久久久国产精品免费 | 99视频精品全部免费免费观看 | 国产无遮挡吃胸膜奶免费看 | 激情综合激情五月俺也去 | 亚洲中文字幕va福利 | 两性色午夜免费视频 | 亲嘴扒胸摸屁股激烈网站 | 亚洲乱码国产乱码精品精 | 任你躁国产自任一区二区三区 | 久久久久久久女国产乱让韩 | 丰满护士巨好爽好大乳 | 久久99精品国产麻豆 | 蜜桃视频插满18在线观看 | 国产99久久精品一区二区 | 极品嫩模高潮叫床 | 自拍偷自拍亚洲精品被多人伦好爽 | 日韩精品一区二区av在线 | 国内揄拍国内精品少妇国语 | 欧美第一黄网免费网站 | 国产激情艳情在线看视频 | 国产精品人人妻人人爽 | 亚洲综合伊人久久大杳蕉 | 东京热无码av男人的天堂 | 高清国产亚洲精品自在久久 | 色综合久久88色综合天天 | 一本久久a久久精品vr综合 | 亚洲色偷偷男人的天堂 | 中文无码伦av中文字幕 | 丰满少妇人妻久久久久久 | 老熟女乱子伦 | 99久久精品无码一区二区毛片 | 香蕉久久久久久av成人 | 国产成人精品视频ⅴa片软件竹菊 | 国产av一区二区精品久久凹凸 | 人人爽人人澡人人人妻 | 久久久久se色偷偷亚洲精品av | 久久精品国产精品国产精品污 | 欧美国产日韩久久mv | 国产尤物精品视频 | 久久久亚洲欧洲日产国码αv | 国产极品美女高潮无套在线观看 | 亚洲人亚洲人成电影网站色 | 久久国产精品萌白酱免费 | 亚洲精品国产品国语在线观看 | 丁香花在线影院观看在线播放 | 国产精品福利视频导航 | 国产午夜无码精品免费看 | 国产精品办公室沙发 | 亚洲日本一区二区三区在线 | 中文字幕无码热在线视频 | 日本丰满护士爆乳xxxx | 亚洲天堂2017无码中文 | 亚洲国产精品美女久久久久 | 少女韩国电视剧在线观看完整 | 欧美熟妇另类久久久久久不卡 | 一个人看的www免费视频在线观看 | 狠狠噜狠狠狠狠丁香五月 | 精品成在人线av无码免费看 | 亚洲呦女专区 | 欧美精品免费观看二区 | 久久精品人人做人人综合试看 | 国产精品99久久精品爆乳 | 久久亚洲日韩精品一区二区三区 | 久久人人97超碰a片精品 | 岛国片人妻三上悠亚 | 水蜜桃亚洲一二三四在线 | 东京无码熟妇人妻av在线网址 | 亚洲の无码国产の无码步美 | 国产精品无码久久av | 成人三级无码视频在线观看 | 奇米影视7777久久精品人人爽 | 丰满肥臀大屁股熟妇激情视频 | 亚洲人成网站在线播放942 | 亚洲国产成人av在线观看 | a在线观看免费网站大全 | 成人精品视频一区二区三区尤物 | 亚洲の无码国产の无码影院 | 一本久久a久久精品vr综合 | 亚洲精品国产第一综合99久久 | 好爽又高潮了毛片免费下载 | 午夜无码人妻av大片色欲 | 蜜臀aⅴ国产精品久久久国产老师 | 色诱久久久久综合网ywww | 天堂а√在线中文在线 | 国精产品一区二区三区 | 国产三级久久久精品麻豆三级 | 中文字幕 亚洲精品 第1页 | 精品一二三区久久aaa片 | 亚洲成熟女人毛毛耸耸多 | 亚洲熟妇色xxxxx欧美老妇 | 国产午夜亚洲精品不卡下载 | 色婷婷av一区二区三区之红樱桃 | 久久精品丝袜高跟鞋 | 中文字幕无码视频专区 | 波多野结衣乳巨码无在线观看 | 欧美35页视频在线观看 | 小sao货水好多真紧h无码视频 | 无码午夜成人1000部免费视频 | 国内少妇偷人精品视频 | 国产精品对白交换视频 | 久久国语露脸国产精品电影 | 欧美放荡的少妇 | 欧美怡红院免费全部视频 | 中文字幕人妻无码一区二区三区 | 毛片内射-百度 | 午夜精品久久久内射近拍高清 | 亚洲国产成人av在线观看 | 少妇性俱乐部纵欲狂欢电影 | 十八禁真人啪啪免费网站 | 亚无码乱人伦一区二区 | 欧美真人作爱免费视频 | 久久久久成人片免费观看蜜芽 | 熟妇人妻无码xxx视频 | 久久久久人妻一区精品色欧美 | 国产超级va在线观看视频 | 成人aaa片一区国产精品 | 18无码粉嫩小泬无套在线观看 | 少妇的肉体aa片免费 | 宝宝好涨水快流出来免费视频 | 久久久精品国产sm最大网站 | 丰满人妻一区二区三区免费视频 | 初尝人妻少妇中文字幕 | 亚洲精品综合一区二区三区在线 | 亚洲国产欧美国产综合一区 | 国产成人精品三级麻豆 | 亚洲精品一区二区三区大桥未久 | 亚洲精品中文字幕乱码 | 久久精品人人做人人综合试看 | 一区二区三区乱码在线 | 欧洲 | 色一情一乱一伦一视频免费看 | 在线看片无码永久免费视频 | 波多野结衣乳巨码无在线观看 | 中国大陆精品视频xxxx | 欧美日韩久久久精品a片 | 激情内射亚州一区二区三区爱妻 | 亚洲国产精品美女久久久久 | 天干天干啦夜天干天2017 | 国产偷自视频区视频 | 丰满人妻翻云覆雨呻吟视频 | 天堂一区人妻无码 | 久精品国产欧美亚洲色aⅴ大片 | 中文字幕乱码人妻无码久久 | 国产97人人超碰caoprom | 成人精品视频一区二区 | 国产成人综合在线女婷五月99播放 | 永久免费精品精品永久-夜色 | 99er热精品视频 | 在线а√天堂中文官网 | 色综合视频一区二区三区 | 国产三级久久久精品麻豆三级 | 精品熟女少妇av免费观看 | 亚洲精品欧美二区三区中文字幕 | 国产成人无码av在线影院 | 精品国偷自产在线视频 | 无码纯肉视频在线观看 | 综合激情五月综合激情五月激情1 | 2019午夜福利不卡片在线 | 免费无码一区二区三区蜜桃大 | 东北女人啪啪对白 | 久久综合狠狠综合久久综合88 | 曰韩无码二三区中文字幕 | 久久人妻内射无码一区三区 | 97精品国产97久久久久久免费 | 精品人妻人人做人人爽夜夜爽 | 又湿又紧又大又爽a视频国产 | 久久国产精品精品国产色婷婷 | 99精品国产综合久久久久五月天 | 精品日本一区二区三区在线观看 | 最近的中文字幕在线看视频 | 红桃av一区二区三区在线无码av | 国产9 9在线 | 中文 | 一本久道久久综合狠狠爱 | 久久精品国产一区二区三区肥胖 | 色欲人妻aaaaaaa无码 | 少妇久久久久久人妻无码 | 国产偷国产偷精品高清尤物 | 蜜桃视频插满18在线观看 | 又粗又大又硬毛片免费看 | 成人无码精品一区二区三区 | 国产亚洲人成在线播放 | 国产办公室秘书无码精品99 | 最新版天堂资源中文官网 | 国产人妻精品午夜福利免费 | 欧美日韩久久久精品a片 | 人妻插b视频一区二区三区 | 日本护士毛茸茸高潮 | 一本无码人妻在中文字幕免费 | 激情内射亚州一区二区三区爱妻 | 18黄暴禁片在线观看 | 国产在线无码精品电影网 | 国产97在线 | 亚洲 | 国产后入清纯学生妹 | 亚洲成av人片在线观看无码不卡 | 精品亚洲韩国一区二区三区 | 午夜精品一区二区三区在线观看 | 天天拍夜夜添久久精品大 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 中文字幕无码免费久久9一区9 | 欧美国产日产一区二区 | 国产偷国产偷精品高清尤物 | 欧美真人作爱免费视频 | 日日摸天天摸爽爽狠狠97 | 色欲av亚洲一区无码少妇 | a在线观看免费网站大全 | 久久国产精品萌白酱免费 | 少妇性荡欲午夜性开放视频剧场 | 高潮喷水的毛片 | а√天堂www在线天堂小说 | 国产精品无码永久免费888 | 亚洲日韩乱码中文无码蜜桃臀网站 | 漂亮人妻洗澡被公强 日日躁 | 亚洲欧洲无卡二区视頻 | 欧美喷潮久久久xxxxx | 18无码粉嫩小泬无套在线观看 | 精品人妻人人做人人爽夜夜爽 | 无码人妻久久一区二区三区不卡 | 蜜臀aⅴ国产精品久久久国产老师 | 亚洲日本在线电影 | 亚洲の无码国产の无码影院 | 久久久久久av无码免费看大片 | 国产精品沙发午睡系列 | 欧美丰满老熟妇xxxxx性 | 欧美变态另类xxxx | 极品嫩模高潮叫床 | 国产精品成人av在线观看 | 亚洲熟悉妇女xxx妇女av | 欧美人与物videos另类 | 亚洲熟悉妇女xxx妇女av | 丰满人妻一区二区三区免费视频 | 亚洲成色在线综合网站 | 亚洲の无码国产の无码影院 | 亚洲色www成人永久网址 | 亚洲区欧美区综合区自拍区 | 性生交片免费无码看人 | 日本乱人伦片中文三区 | 无码人妻精品一区二区三区不卡 | 97久久国产亚洲精品超碰热 | 人人爽人人爽人人片av亚洲 | 欧美日本精品一区二区三区 | 国产av无码专区亚洲awww | 奇米影视7777久久精品 | 少妇邻居内射在线 | 熟妇激情内射com | 国产高清av在线播放 | 精品国产av色一区二区深夜久久 | 国产免费久久久久久无码 | 欧美老妇交乱视频在线观看 | 性生交大片免费看女人按摩摩 | 牲欲强的熟妇农村老妇女 | 久久99精品久久久久久 | 国产极品美女高潮无套在线观看 | 精品一区二区三区波多野结衣 | 亚洲国产成人a精品不卡在线 | 日本大乳高潮视频在线观看 | 国产av无码专区亚洲awww | 久久久久久久人妻无码中文字幕爆 | 97夜夜澡人人双人人人喊 | 丝袜 中出 制服 人妻 美腿 | 亚洲精品久久久久久一区二区 | 久久精品人人做人人综合 | 波多野结衣 黑人 | 福利一区二区三区视频在线观看 | 亚洲综合另类小说色区 | 天天摸天天透天天添 | 久久aⅴ免费观看 | 东京热男人av天堂 | 成人影院yy111111在线观看 | 麻豆国产人妻欲求不满 | 在线看片无码永久免费视频 | 亚洲乱码中文字幕在线 | 欧美日韩一区二区免费视频 | 东京一本一道一二三区 | 免费乱码人妻系列无码专区 | 蜜桃臀无码内射一区二区三区 | √8天堂资源地址中文在线 | 亚洲a无码综合a国产av中文 | 无码人妻丰满熟妇区毛片18 | 装睡被陌生人摸出水好爽 | 日欧一片内射va在线影院 | 欧美 亚洲 国产 另类 | 国产精品美女久久久 | 东京热无码av男人的天堂 | 99视频精品全部免费免费观看 | 亚洲国产精品无码久久久久高潮 | 久久综合网欧美色妞网 | 中文字幕无码人妻少妇免费 | 日本在线高清不卡免费播放 | 亚洲日韩av一区二区三区四区 | 亚洲一区二区三区无码久久 | 131美女爱做视频 | 色综合视频一区二区三区 | 国产精品无码mv在线观看 | 亚洲热妇无码av在线播放 | 亚洲国产av精品一区二区蜜芽 | 2019nv天堂香蕉在线观看 | 国产无遮挡又黄又爽又色 | 亚洲色成人中文字幕网站 | 麻豆av传媒蜜桃天美传媒 | 久久人人97超碰a片精品 | 国产综合在线观看 | 又大又黄又粗又爽的免费视频 | 国产区女主播在线观看 | 国产av一区二区三区最新精品 | 精品国产国产综合精品 | 亚洲色www成人永久网址 | 亚洲成a人片在线观看日本 | √天堂资源地址中文在线 | 青青青爽视频在线观看 | 午夜性刺激在线视频免费 | 亚洲精品中文字幕乱码 | 亚洲一区二区三区含羞草 | 一本久道久久综合狠狠爱 | 亚洲国产精品成人久久蜜臀 | 国产精品国产自线拍免费软件 | 精品人妻中文字幕有码在线 | 无码毛片视频一区二区本码 | 欧美日韩在线亚洲综合国产人 | 欧美高清在线精品一区 | 色诱久久久久综合网ywww | 国产午夜亚洲精品不卡下载 | 麻豆果冻传媒2021精品传媒一区下载 | 内射后入在线观看一区 | 欧美成人高清在线播放 | 国产精品香蕉在线观看 | 伊人久久婷婷五月综合97色 | 性生交大片免费看l | 久久国产精品偷任你爽任你 | 精品熟女少妇av免费观看 | 性欧美大战久久久久久久 | 久久99精品国产.久久久久 | 97精品人妻一区二区三区香蕉 | 成人试看120秒体验区 | 极品嫩模高潮叫床 | 女人被爽到呻吟gif动态图视看 | 十八禁真人啪啪免费网站 | 亚洲伊人久久精品影院 | 又大又硬又黄的免费视频 | www成人国产高清内射 | 精品久久久久久亚洲精品 | 少妇性荡欲午夜性开放视频剧场 | 亚洲va欧美va天堂v国产综合 | 色婷婷久久一区二区三区麻豆 | 国产精品无码一区二区桃花视频 | 国产日产欧产精品精品app | 中文字幕乱妇无码av在线 | 亚洲国产精品久久久久久 | 在线播放免费人成毛片乱码 | 黑人玩弄人妻中文在线 | 无码吃奶揉捏奶头高潮视频 | 国产特级毛片aaaaaa高潮流水 | 成人女人看片免费视频放人 | 人人妻在人人 | 久久五月精品中文字幕 | 成人精品一区二区三区中文字幕 | 波多野结衣一区二区三区av免费 | 欧美zoozzooz性欧美 | 国产无av码在线观看 | 国产精品成人av在线观看 | 国产精品亚洲五月天高清 | 漂亮人妻洗澡被公强 日日躁 | √天堂资源地址中文在线 | 国产精品亚洲lv粉色 | 99国产欧美久久久精品 | 亚洲精品午夜国产va久久成人 | 亚洲综合无码久久精品综合 | 男人扒开女人内裤强吻桶进去 | 久久久久久av无码免费看大片 | 67194成是人免费无码 | 高中生自慰www网站 | 少妇无套内谢久久久久 | 一二三四在线观看免费视频 | 色婷婷香蕉在线一区二区 | 5858s亚洲色大成网站www | 秋霞成人午夜鲁丝一区二区三区 | 精品 日韩 国产 欧美 视频 | 在线看片无码永久免费视频 | 中国女人内谢69xxxxxa片 | 最新版天堂资源中文官网 | 少妇无码av无码专区在线观看 | 精品国产一区二区三区av 性色 | 丰满人妻一区二区三区免费视频 | 国产明星裸体无码xxxx视频 | 国产一区二区不卡老阿姨 | 老熟妇乱子伦牲交视频 | 日本饥渴人妻欲求不满 | 少妇邻居内射在线 | 在线播放亚洲第一字幕 | 国产黑色丝袜在线播放 | 国产精品丝袜黑色高跟鞋 | 大胆欧美熟妇xx | 亚洲无人区午夜福利码高清完整版 | 性欧美牲交xxxxx视频 | 久久天天躁狠狠躁夜夜免费观看 | 一本久道久久综合狠狠爱 | 欧美三级a做爰在线观看 | 97精品国产97久久久久久免费 | 最近免费中文字幕中文高清百度 | 无套内射视频囯产 | 国产性生大片免费观看性 | 无码播放一区二区三区 | 国产人妻精品午夜福利免费 | 撕开奶罩揉吮奶头视频 | 国产av人人夜夜澡人人爽麻豆 | 国产精品毛多多水多 | 国产免费久久久久久无码 | 无码人妻久久一区二区三区不卡 | 狠狠躁日日躁夜夜躁2020 | 国产精品毛多多水多 | 精品久久8x国产免费观看 | 无码人中文字幕 | 中文字幕无线码 | 欧美色就是色 | 欧美精品一区二区精品久久 | 久久精品中文字幕大胸 | 国内综合精品午夜久久资源 | 国产亚洲精品精品国产亚洲综合 | 亚洲国产精品美女久久久久 | 88国产精品欧美一区二区三区 | 欧美一区二区三区视频在线观看 | 99久久亚洲精品无码毛片 | 亚洲人成影院在线无码按摩店 | 牲欲强的熟妇农村老妇女 | 国产人成高清在线视频99最全资源 | 双乳奶水饱满少妇呻吟 | 欧美黑人性暴力猛交喷水 | 精品欧洲av无码一区二区三区 | 日本成熟视频免费视频 | 日本护士毛茸茸高潮 | 国产精品a成v人在线播放 | 四虎国产精品免费久久 | 妺妺窝人体色www在线小说 | 性欧美videos高清精品 | 婷婷丁香六月激情综合啪 | 综合激情五月综合激情五月激情1 | 成人av无码一区二区三区 | 乱码av麻豆丝袜熟女系列 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 特大黑人娇小亚洲女 | 国产亚洲日韩欧美另类第八页 | 久久精品国产大片免费观看 | 东京一本一道一二三区 | 亚洲午夜无码久久 | 国产欧美精品一区二区三区 | 国产精品多人p群无码 | 久久无码人妻影院 | 国产乱人伦av在线无码 | 欧美成人午夜精品久久久 | 日本肉体xxxx裸交 | 日韩人妻无码一区二区三区久久99 | 欧美丰满熟妇xxxx | 亚洲人成网站在线播放942 | 久久久国产精品无码免费专区 | yw尤物av无码国产在线观看 | 亚洲春色在线视频 | 在线欧美精品一区二区三区 | 妺妺窝人体色www在线小说 | 亚洲色欲色欲天天天www | 成人免费视频一区二区 | 粗大的内捧猛烈进出视频 | 亚洲の无码国产の无码影院 | 国产亚洲视频中文字幕97精品 | 午夜福利一区二区三区在线观看 | 性色av无码免费一区二区三区 | 极品嫩模高潮叫床 | 欧美三级不卡在线观看 | 中文字幕人妻无码一夲道 | 亚洲欧美日韩国产精品一区二区 | 噜噜噜亚洲色成人网站 | 四十如虎的丰满熟妇啪啪 | 国产一区二区三区影院 | 国产人妻精品午夜福利免费 | 欧美阿v高清资源不卡在线播放 | 精品国产国产综合精品 | 青青青手机频在线观看 | 99久久久国产精品无码免费 | 国产午夜视频在线观看 | 波多野结衣一区二区三区av免费 | 欧美人与禽zoz0性伦交 | 人人爽人人澡人人人妻 | a国产一区二区免费入口 | 久久精品中文字幕大胸 | 亚洲精品国偷拍自产在线麻豆 | 色婷婷久久一区二区三区麻豆 | 中文字幕人妻无码一区二区三区 | 国产69精品久久久久app下载 | 天下第一社区视频www日本 | 鲁鲁鲁爽爽爽在线视频观看 | 超碰97人人做人人爱少妇 | 免费播放一区二区三区 | 黑人粗大猛烈进出高潮视频 | 人妻熟女一区 | 国模大胆一区二区三区 | 精品夜夜澡人妻无码av蜜桃 | 在线亚洲高清揄拍自拍一品区 | 高潮毛片无遮挡高清免费视频 | 国产成人无码区免费内射一片色欲 | 在线欧美精品一区二区三区 | 色一情一乱一伦 | 日韩精品久久久肉伦网站 | 亚洲欧美精品aaaaaa片 | 2020久久超碰国产精品最新 | 99国产精品白浆在线观看免费 | 久久久久99精品国产片 | 少妇被黑人到高潮喷出白浆 | 中文字幕 人妻熟女 | 大色综合色综合网站 | 免费无码肉片在线观看 | 99久久精品午夜一区二区 | 亚洲成av人影院在线观看 | 欧美亚洲国产一区二区三区 | 永久黄网站色视频免费直播 | 国产香蕉尹人综合在线观看 | 色欲人妻aaaaaaa无码 | 一本无码人妻在中文字幕免费 | 久久久久久久女国产乱让韩 | 人人澡人人透人人爽 | 天天摸天天透天天添 | 人人妻人人澡人人爽人人精品 | 亚洲中文字幕在线无码一区二区 | 成人影院yy111111在线观看 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 一个人免费观看的www视频 | 狂野欧美激情性xxxx | 国产做国产爱免费视频 | 中文字幕av伊人av无码av | 国内少妇偷人精品视频 | 久久综合激激的五月天 | 亚洲日本va午夜在线电影 | 日本www一道久久久免费榴莲 | 小sao货水好多真紧h无码视频 | 国产成人无码av在线影院 | 亚洲人交乣女bbw | 无码中文字幕色专区 | 熟女体下毛毛黑森林 | 欧美喷潮久久久xxxxx | 丰满少妇熟乱xxxxx视频 | 中文字幕无码免费久久9一区9 | 熟女少妇在线视频播放 | 中国大陆精品视频xxxx | 成人性做爰aaa片免费看 | 四虎国产精品免费久久 | 色欲av亚洲一区无码少妇 | 在线天堂新版最新版在线8 | 亚洲精品欧美二区三区中文字幕 | 黑人大群体交免费视频 | 中文字幕av日韩精品一区二区 | 无套内谢老熟女 | 亚洲精品国产第一综合99久久 | 任你躁国产自任一区二区三区 | 日韩人妻无码一区二区三区久久99 | 日日噜噜噜噜夜夜爽亚洲精品 | 欧美激情一区二区三区成人 | 欧美国产日产一区二区 | 欧美熟妇另类久久久久久不卡 | 天天av天天av天天透 | 欧美人与禽猛交狂配 | 亚洲第一网站男人都懂 | 亚洲成a人片在线观看无码 | 亚洲精品无码国产 | 在线观看欧美一区二区三区 | 国产 浪潮av性色四虎 | 久久无码专区国产精品s | 国产肉丝袜在线观看 | 亚洲va欧美va天堂v国产综合 | 久久亚洲日韩精品一区二区三区 | 久久99精品国产麻豆蜜芽 | 日本熟妇大屁股人妻 | 成 人 免费观看网站 | 国产精品久久久久久亚洲毛片 | 高潮毛片无遮挡高清免费视频 | 亚洲熟熟妇xxxx | 亚洲精品成人av在线 | 丰满人妻精品国产99aⅴ | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 精品久久8x国产免费观看 | 欧美freesex黑人又粗又大 | 奇米影视888欧美在线观看 | 国产人妻精品一区二区三区不卡 | 精品国产青草久久久久福利 | 日日橹狠狠爱欧美视频 | 亚洲码国产精品高潮在线 | 亚洲春色在线视频 | 亚洲一区av无码专区在线观看 | 一个人看的www免费视频在线观看 | 国产明星裸体无码xxxx视频 | 成人无码精品一区二区三区 | 中文字幕无码日韩专区 | 亚洲人成影院在线观看 | 国产 精品 自在自线 | 国内老熟妇对白xxxxhd | 欧美精品无码一区二区三区 | 国产激情综合五月久久 | 久久亚洲精品成人无码 | 国产极品美女高潮无套在线观看 | 红桃av一区二区三区在线无码av | 无码人妻出轨黑人中文字幕 | 在线精品国产一区二区三区 | 人人妻人人澡人人爽欧美精品 | 牲交欧美兽交欧美 | 熟妇人妻无码xxx视频 | 色综合久久久无码网中文 | 丰满岳乱妇在线观看中字无码 | 久久精品中文字幕一区 | 国产乱码精品一品二品 | 亚洲人成影院在线观看 | 5858s亚洲色大成网站www | 国产午夜视频在线观看 | 亚洲一区二区三区国产精华液 |