亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Swift > 正文

Swift教程之函數詳解

2020-03-09 17:51:20
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了Swift教程之函數詳解,本文講解了函數的聲明與調用、函數的參數和返回值、函數參數名、函數類型等內容,需要的朋友可以參考下
 

函數是執行特定任務的代碼自包含塊。給定一個函數名稱標識, 當執行其任務時就可以用這個標識來進行”調用”。

Swift的統一的功能語法足夠靈活來表達任何東西,無論是甚至沒有參數名稱的簡單的C風格的函數表達式,還是需要為每個本地參數和外部參數設置復雜名稱的Objective-C語言風格的函數。參數提供默認值,以簡化函數調用,并通過設置在輸入輸出參數,在函數執行完成時修改傳遞的變量。

Swift中的每個函數都有一個類型,包括函數的參數類型和返回類型。您可以方便的使用此類型像任何其他類型一樣,這使得它很容易將函數作為參數傳遞給其他函數,甚至從函數中返回函數類型。函數也可以寫在其他函數中來封裝一個嵌套函數用以范圍內有用的功能。

1、函數的聲明與調用

當你定義一個函數時,你可以為其定義一個或多個不同名稱、類型值作為函數的輸入(稱為參數),當該函數完成時將傳回輸出定義的類型(稱為作為它的返回類型)。

每一個函數都有一個函數名,用來描述了函數執行的任務。要使用一個函數的功能時,你通過使用它的名稱進行“調用”,并通過它的輸入值(稱為參數)來匹配函數的參數類型。一個函數的提供的參數必須始終以相同的順序來作為函數參數列表。

例如在下面的例子中被調用的函數greetingForPerson,像它描述的那樣 — 它需要一個人的名字作為輸入并返回一句問候給那個人。

 

復制代碼代碼如下:
 
func sayHello(personName: String) -> String {
let greeting = "Hello, " + personName + "!"
return greeting
}

所有這些信息都匯總到函數的定義中,并以func關鍵字為前綴。您指定的函數的返回類型是以箭頭->(一個連字符后跟一個右尖括號)以及隨后類型的名稱作為返回的。

 

該定義描述了函數的作用是什么,它期望接收什么,以及當它完成返回的結果是什么。該定義很容易讓該函數可以讓你在代碼的其他地方以清晰、明確的方式來調用:

 

復制代碼代碼如下:

println(sayHello("Anna"))
// prints "Hello, Anna!"
println(sayHello("Brian"))
// prints "Hello, Brian!"

通過括號內String類型參數值調用sayHello的函數,如的sayHello(”Anna”)。由于該函數返回一個字符串值,sayHello的可以被包裹在一個println函數調用中來打印字符串,看看它的返回值,如上圖所示。

 

在sayHello的函數體開始定義了一個新的名為greeting的String常量,并將其設置加上personName個人姓名組成一句簡單的問候消息。然后這個問候函數以關鍵字return來傳回。只要問候函數被調用時,函數執行完畢是就會返回問候語的當前值。

你可以通過不同的輸入值多次調用sayHello的函數。上面的例子顯示了如果它以”Anna”為輸入值,以”Brian”為輸入值會發生什么。函數的返回在每種情況下都是量身定制的問候。

為了簡化這個函數的主體,結合消息創建和return語句用一行來表示:

 

復制代碼代碼如下:
 
func sayHello(personName: String) -> String {
return "Hello again, " + personName + "!"
}
println(sayHello("Anna"))
// prints "Hello again, Anna!"

2、函數的參數和返回值

 

在swift中函數的參數和返回值是非常具有靈活性的。你可以定義任何東西無論是一個簡單的僅僅有一個未命名的參數的函數還是那種具有豐富的參數名稱和不同的參數選項的復雜函數。

多輸入參數

函數可以有多個輸入參數,把他們寫到函數的括號內,并用逗號加以分隔。下面這個函數設置了一個開始和結束索引的一個半開區間,用來計算在范圍內有多少元素包含:

 

復制代碼代碼如下:

func halfOpenRangeLength(start: Int, end: Int) -> Int {
return end - start
}
println(halfOpenRangeLength(1, 10))
// prints "9"

無參函數

 

函數并沒有要求一定要定義的輸入參數。下面就一個沒有輸入參數的函數,任何時候調用時它總是返回相同的字符串消息:

 

復制代碼代碼如下:
 
func sayHelloWorld() -> String {
return "hello, world"
}
println(sayHelloWorld())
// prints "hello, world"

該函數的定義在函數的名稱后還需要括號,即使它不帶任何參數。當函數被調用時函數名稱也要跟著一對空括號。

 

沒有返回值的函數

函數也不需要定義一個返回類型。這里有一個版本的sayHello的函數,稱為waveGoodbye,它會輸出自己的字符串值而不是函數返回:

 

復制代碼代碼如下:

func sayGoodbye(personName: String) {
println("Goodbye, /(personName)!")
}
sayGoodbye("Dave")
// prints "Goodbye, Dave!"

因為它并不需要返回一個值,該函數的定義不包括返回箭頭( – >)和返回類型。

 

提示
嚴格地說,sayGoodbye功能確實還返回一個值,即使沒有返回值定義。函數沒有定義返回類型但返
回了一個void返回類型的特殊值。它是一個簡直是空的元組,實際上零個元素的元組,可以寫為()。
當一個函數調用時它的返回值可以忽略不計:

 

復制代碼代碼如下:

func printAndCount(stringToPrint: String) -> Int {
println(stringToPrint)
return countElements(stringToPrint)
}
func printWithoutCounting(stringToPrint: String) {
printAndCount(stringToPrint)
}
printAndCount("hello, world")
// prints "hello, world" and returns a value of 12
printWithoutCounting("hello, world")
// prints "hello, world" but does not return a value

第一個函數printAndCount,打印了一個字符串,然后并以Int類型返回它的字符數。第二個函數printWithoutCounting,調用的第一個函數,但忽略它的返回值。當第二函數被調用時,字符串消息由第一函數打印了回來,去沒有使用其返回值。

 

提示

返回值可以忽略不計,但對一個函數來說,它的返回值即便不使用還是一定會返回的。在函數體底部
返回時與定義的返回類型的函數不能相容時,如果試圖這樣做將導致一個編譯時錯誤。

多返回值函數

你可以使用一個元組類型作為函數的返回類型返回一個有多個值組成的一個復合作為返回值。

下面的例子定義了一個名為count函數,用它計來算字符串中基于標準的美式英語中設定使用的元音、輔音以及字符的數量:

 

復制代碼代碼如下:
 
func count(string: String) -> (vowels: Int, consonants: Int, others: Int) {
var vowels = 0, consonants = 0, others = 0
for character in string {
switch String(character).lowercaseString {
case "a", "e", "i", "o", "u":
++vowels
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
"n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
++consonants
default:
++others
}
}
return (vowels, consonants, others)
}

您可以使用此計數函數來對任意字符串進行字符計數,并檢索統計總數的元組三個指定Int值:

 

 

復制代碼代碼如下:
 
let total = count("some arbitrary string!")
println("/(total.vowels) vowels and /(total.consonants) consonants")
// prints "6 vowels and 13 consonants"

需要注意的是在這一點上元組的成員不需要被命名在該該函數返回的元組中,因為他們的名字已經被指定為函數的返回類型的一部分。

 

3、函數參數名

所有上面的函數都為參數定義了參數名稱:

 

復制代碼代碼如下:
 
func someFunction(parameterName: Int) {
// function body goes here, and can use parameterName
// to refer to the argument value for that parameter
}

然而,這些參數名的僅能在函數本身的主體內使用,在調用函數時,不能使用。這些類型的參數名稱被稱為本地的參數,因為它們只適用于函數體中使用。

 

外部參數名

有時當你調用一個函數將每個參數進行命名是非常有用的,以表明你傳遞給函數的每個參數的目的。

如果你希望用戶函數調用你的函數時提供參數名稱,除了設置本地地的參數名稱,也要為每個參數定義外部參數名稱。你寫一個外部參數名稱在它所支持的本地參數名稱之前,之間用一個空格來分隔:

 

復制代碼代碼如下:

func someFunction(externalParameterName localParameterName: Int) {
// function body goes here, and can use localParameterName
// to refer to the argument value for that parameter
}

 

注意

如果您為參數提供一個外部參數名稱,調用該函數時外部名稱必須始終被使用。
作為一個例子,考慮下面的函數,它通過插入他們之間的第三個”joiner”字符串來連接兩個字符串:

 

復制代碼代碼如下:

func join(s1: String, s2: String, joiner: String) -> String {
return s1 + joiner + s2
}

當你調用這個函數,你傳遞給函數的三個字符串的目的就不是很清楚了:

 

 

復制代碼代碼如下:

join("hello", "world", ", ")
// returns "hello, world"

為了使這些字符串值的目的更為清晰,為每個join函數參數定義外部參數名稱:

 

 

復制代碼代碼如下:
 
func join(string s1: String, toString s2: String, withJoiner joiner: String)
-> String {
return s1 + joiner + s2
}

在這個版本的join函數中,第一個參數有一個外部名稱string和一個本地名稱s1;第二個參數有一個外部名稱toString和一個本地名稱s2;第三個參數有一個外部名稱withJoiner和一個本地名稱joiner。

 

現在,您可以使用這些外部參數名稱調用清楚明確的調用該函數:

 

復制代碼代碼如下:

join(string: "hello", toString: "world", withJoiner: ", ")
// returns "hello, world"

使用外部參數名稱使join函數的第二個版本功能更富有表現力,用戶習慣使用sentence-like的方式,同時還提供了一個可讀的、意圖明確的函數體。

 

注意

考慮到使用外部參數名稱的初衷就是為了在別人第一次閱讀你的代碼時并不知道你函數參數的目的是什么。
但當函數調用時如果每個參數的目的是明確的和毫不含糊的,你并不需要指定外部參數名稱。

外部參數名稱速記

如果你想為一個函數參數提供一個外部參數名,然而本地參數名已經使用了一個合適的名稱了,你不需要為該參數寫相同的兩次名稱。取而代之的是,寫一次名字,并用一個hash符號(#)作為名稱的前綴。這告訴Swift使用該名稱同時作為本地參數名稱和外部參數名稱。

這個例子定義了一個名為containsCharacter的函數,定義了兩個參數的外部參數名稱并通過放置一個散列標志在他們本地參數名稱之前:

 

復制代碼代碼如下:

func containsCharacter(#string: String, #characterToFind: Character) -> Bool {
for character in string {
if character == characterToFind {
return true
}
}
return false
}

這個函數選擇的參數名稱清晰的、函數體極具可讀性,使的該函數被調用時沒有歧義:

 

 

復制代碼代碼如下:
 
let containsAVee = containsCharacter(string: "aardvark", characterToFind: "v")
// containsAVee equals true, because "aardvark" contains a "v"

 

參數的默認值

可以為任何參數設定默認值來作為函數的定義的一部分。如果默認值已經定義,調用函數時就可以省略該參數的傳值。

注意

將使用默認值的參數放在函數的參數列表的末尾。這確保了所有調用函數的非默認參數使用相同的順
序,并明確地表示在每種情況下相同的函數調用。
這里有一個版本,是早期的join函數,并為參數joiner設置了默認值:

 

復制代碼代碼如下:
 
func join(string s1: String, toString s2: String,
withJoiner joiner: String = " ") -> String {
return s1 + joiner + s2
}

如果在join函數被調用時提供給joiner一個字符串值,該字符串是用來連接兩個字符串,就跟以前一樣:

 

 

復制代碼代碼如下:

join(string: "hello", toString: "world", withJoiner: "-")
// returns "hello-world"

 

但是,如果當函數被調用時提供了joiner的沒有值,就會使用單個空格(” “)的默認值:

 

復制代碼代碼如下:
 
join(string: "hello", toString: "world")
// returns "hello world"

 

有默認值的外部名稱參數

在大多數情況下,為所有參數提供一個外部帶有默認值的參數的名稱是非常有用的(因此要求)。這將確如果當函數被調用時提供的值時參數必須具有明確的目的。

為了使這個過程更容易,當你自己沒有提供外部名稱時,Swift自動為所有參數定義了缺省的參數外部名稱。自動外部名稱與本地名稱相同,就好像你在你的代碼中的本地名稱之前寫了一個hash符號。

這里有一個早期join函數版本,它不為任何參數提供的外部名稱,但仍然提供了joiner參數的默認值:

 

復制代碼代碼如下:
 
func join(s1: String, s2: String, joiner: String = " ") -> String {
return s1 + joiner + s2
}

在這種情況下,Swift自動為一個具有默認值的參數提供了外部參數名稱。調用函數時,為使得參數的目的明確、毫不含糊,因此必須提供外部名稱:

 

 

復制代碼代碼如下:
 
join("hello", "world", joiner: "-")
// returns "hello-world"

 

注意

你可以通過編寫一個下劃線(_)有選擇進行這種行為,而不是一個明確的定義外部參數名稱。然
而,在適當情況下有默認值的外部名稱參數總是優先被使用。

可變參數

一個可變參數的參數接受零個或多個指定類型的值。當函數被調用時,您可以使用一個可變參數的參數來指定該參數可以傳遞不同數量的輸入值。寫可變參數的參數時,需要參數的類型名稱后加上點字符(…)。

傳遞一個可變參數的參數的值時,函數體中是以提供適當類型的數組的形式存在。例如,一個可變參數的名稱為numbers和類型為Double…在函數體內就作為名為numbers類型為Double[]的常量數組。

下面的示例計算任意長度的數字的算術平均值(也稱為平均):

 

復制代碼代碼如下:
 
func arithmeticMean(numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8, 19)
// returns 10.0, which is the arithmetic mean of these three numbers

 

注意

函數可以最多有一個可變參數的參數,而且它必須出現在參數列表的最后以避免多參數函
數調用時出現歧義。

如果函數有一個或多個參數使用默認值,并且還具有可變參數,將可變參數放在列表的
最末尾的所有默認值的參數之后。

常量參數和變量參數

函數參數的默認值都是常量。試圖改變一個函數參數的值會讓這個函數體內部產生一個編譯時錯誤。這意味著您不能錯誤地改變參數的值。

但是,有時函數有一個參數的值的變量副本是非常有用的。您可以通過指定一個或多個參數作為變量參數,而不是避免在函數內部為自己定義一個新的變量。變量參數可以是變量而不是常量,并給函數中新修改的參數的值的提供一個副本。

在參數名稱前用關鍵字var定義變量參數:

 

復制代碼代碼如下:
 
func alignRight(var string: String, count: Int, pad: Character) -> String {
let amountToPad = count - countElements(string)
for _ in 1...amountToPad {
string = pad + string
}
return string
}
let originalString = "hello"
let paddedString = alignRight(originalString, 10, "-")
// paddedString is equal to "-----hello"
// originalString is still equal to "hello"

 

這個例子定義了一個新函數叫做alignRight,它對準一個輸入字符串,以一個較長的輸出字符串。在左側的空間中填充規定的字符。在該示例中,字符串”hello”被轉換為字符串”—–hello”。

該alignRight函數把輸入參數的字符串定義成了一個變量參數。這意味著字符串現在可以作為一個局部變量,用傳入的字符串值初始化,并且可以在函數體中進行相應操作。

函數首先找出有多少字符需要被添加到左邊讓字符串以右對齊在整個字符串中。這個值存儲在本地常量amountToPad中。該函數然后將填充字符的amountToPad個字符拷貝到現有的字符串的左邊,并返回結果。整個過程使用字符串變量參數進行字符串操作。

注意

一個變量參數的變化沒有超出了每個調用函數,所以對外部函數體是不可見的。變量參數只能存在于函數調用
的生命周期里。

輸入-輸出參數

可變參數,如上所述,只能在函數本身內改變。如果你想有一個函數來修改參數的值,并且想讓這些變化要堅持在函數調用結束后,你就可以定義輸入-輸出參數來代替。

通過在其參數定義的開始添加inout關鍵字寫用來標明輸入-輸出參數。一個在輸入-輸出參數都有一個傳遞給函數的值,由函數修改后,并從函數返回來替換原來的值。

4、函數類型

每個函數都有一個特定的類型,包括參數類型和返回值類型,比如:

 

復制代碼代碼如下:

func addTwoInts(a: Int, b: Int) -> Int {
    return a + b
}
func multiplyTwoInts(a: Int, b: Int) -> Int {
    return a * b
}

 

這個例子定義了兩個簡單的數學函數addTwoInts和multiplyTwoInts。每個函數接受兩個int參數,返回一個int值,執行相應的數學運算然后返回結果

這兩個函數的類型是(Int, Int)->Int可以解釋為:

這個函數類型它有兩個int型的參數,并返回一個int類型的值

下面這個例子是一個不帶任何參數和返回值的函數:

 

復制代碼代碼如下:
 
func printHelloWorld() {
    println("hello, world")
}

這個函數的類型是()->(),或者函數沒有參數,返回void。函數沒有顯式地指定返回類型,默認為void,在Swift中相當于一個空元組,記為()。

 

使用函數類型

在swift中你可以像任何其他類型一樣的使用函數類型。例如,你可以定義一個常量或變量為一個函數類型,并指定適當的函數給該變量:

 

復制代碼代碼如下:

var mathFunction: (Int, Int) -> Int = addTwoInts

可以解讀為:

 

“定義一個名為mathFunction變量,該變量的類型為'一個函數,它接受兩個int值,并返回一個int值。'設置這個新的變量來引用名為addTwoInts函數的功能。”

該mathFunction函數具有與addTwoInts函數相同類型的變量,所以這個賦值能通過Swift的類型檢查。

現在你可以調用指定的函數名稱為mathFunction:

 

復制代碼代碼如下:

println("Result: /(mathFunction(2, 3))")
// prints "Result: 5"

不同的函數相同的匹配類型可以分配給相同的變量,也同樣的適用于非函數性類型:

 

 

復制代碼代碼如下:
 
mathFunction = multiplyTwoInts
println("Result: /(mathFunction(2, 3))")
// prints "Result: 6"

與其他類型一樣,你可以把它迅速定義成函數類型當你為常量或變量分配一個函數時:

 

 

復制代碼代碼如下:

let anotherMathFunction = addTwoInts
// anotherMathFunction is inferred to be of type (Int, Int) -> Int

 

函數類型的參數

可以使用一個函數類型,如(Int, Int)->Int作為另一個函數的參數類型。這使你預留了一個函數的某些方面的實現,讓調用者調用函數時提供。

下面就以打印上面的數學函數的結果為例:

 

復制代碼代碼如下:
 
func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) {
    println("Result: /(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)
// prints "Result: 8"

這個例子中定義了一個名為printMathResult函數,它有三個參數。第一個參數名為mathFunction,類型為(Int, Int)->Int。您可以傳入符合條件的任何函數類型作為此函數的第一個參數。第二和第三個參數a、b都是int類型。被用作于提供數學函數的兩個輸入值。

 

當printMathResult被調用時,它傳遞addTwoInt函數,以及整數值3和5。它使用3和5,調用addTwoInt函數,并打印函數運行的結果8。

printMathResult的作用是調用一個適當類型的數學函數并打印相應結果。那是什么功能的實現其實并不重要,你只要給以正確的類型匹配就行。這使printMathResult以調用者類型安全的方式轉換了函數的功能。

函數類型的返回值

可以使用一個函數類型作為另一個函數的返回類型。返回的函數(->)即你的返回箭頭后,立即寫一個完整的函數類型就做到這一點。
下面的例子定義了兩個簡單的函數,分別是stepForward和stepBackward。stepForward函數返回輸入值自增1,而stepBackward函數返回輸入值自減1。這兩個函數都有一個相同的類型 (Int) -> Int:

 

復制代碼代碼如下:
 
func stepForward(input: Int) -> Int {
    return input + 1
}
func stepBackward(input: Int) -> Int {
    return input - 1
}

這里有一個chooseStepFunction函數,它的返回類型是”函數類型(Int) -> Int”。chooseStepFunction返回一個基于布爾參數的stepBackward或stepForward函數類型:

 

 

復制代碼代碼如下:
 
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    return backwards ? stepBackward : stepForward
}

您現在可以使用chooseStepFunction選擇一個函數,可能是加一函數或另一個:

 

 

復制代碼代碼如下:

var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero now refers to the stepBackward() function

上述例子可以判斷步驟的正負決定是否需要移動使得currentValue變量逐步接近零。currentValue初始值是3,這意味著當前值>0,則返回true,chooseStepFunction返回stepBackward函數。返回函數的引用存儲在一個稱為moveNearerToZero常量里。
如今moveNearerToZero執行了正確的功能,就可以用來計數到零:

 

 

復制代碼代碼如下:
 
println("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
println("/(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
}
println("zero!")
// 3...
// 2...
// 1...
// zero!

5、嵌套函數

 

迄今為止所有你在本章中遇到函數都是全局函數,在全局范圍內定義。其實你還可以在其他函數中定義函數,被稱為嵌套函數。

嵌套函數默認對外界是隱藏的,但仍然可以調用和使用其內部的函數。內部函數也可以返回一個嵌套函數,允許在嵌套函數內的另一個范圍內使用。

你可以重寫上面的chooseStepFunction例子使用并返回嵌套函數:

 

復制代碼代碼如下:
 
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
func stepForward(input: Int) -> Int { return input + 1 }
func stepBackward(input: Int) -> Int { return input - 1 }
return backwards ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero now refers to the nested stepForward() function
while currentValue != 0 {
println("/(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
}
println("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!


注:相關教程知識閱讀請移步到swift教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产婷婷成人久久av免费高清| 日本午夜精品理论片a级appf发布| 久久99热精品这里久久精品| 伊人av综合网| 最近2019中文免费高清视频观看www99| 精品日韩中文字幕| 亚洲欧美中文在线视频| 91成人精品网站| 国产精品吴梦梦| 日韩亚洲欧美成人| 日韩一区二区精品视频| 精品综合久久久久久97| 国产成人精品日本亚洲| 亚洲国产精彩中文乱码av在线播放| 欧美重口另类videos人妖| 国产精品69精品一区二区三区| 韩国欧美亚洲国产| 欧美丝袜美女中出在线| 一区二区三区四区精品| 欧美黑人xxxx| 国产精品国产三级国产aⅴ浪潮| 久久影院免费观看| 亚洲免费人成在线视频观看| 久久免费在线观看| 91免费精品视频| 欧美日本精品在线| 亚洲欧洲国产伦综合| 国产丝袜视频一区| 国产精品福利网| 欧美性黄网官网| 九色精品免费永久在线| 黑人欧美xxxx| 一本色道久久88综合亚洲精品ⅰ| 亚洲最大成人在线| 国产精品久久久久久久久久久新郎| 日韩美女福利视频| 久久夜色精品国产亚洲aⅴ| 91国产精品视频在线| 精品国产乱码久久久久久婷婷| 亚洲男人的天堂在线| 国产精品免费一区豆花| 久久成人亚洲精品| 激情成人中文字幕| 久久久精品一区二区| 2025国产精品视频| 丝袜美腿亚洲一区二区| 欧美日韩中文字幕在线| 日本a级片电影一区二区| 国产精品激情av在线播放| 日韩成人激情视频| 日韩在线视频线视频免费网站| 亚洲色图第三页| 亚洲精品国产精品国产自| 亚洲综合在线播放| 欧美黑人性猛交| 51ⅴ精品国产91久久久久久| 日韩欧美一区视频| 国产午夜精品全部视频播放| 亚洲精品久久久一区二区三区| 爽爽爽爽爽爽爽成人免费观看| 国产一区二区日韩| 欧美性生交xxxxx久久久| 日韩欧美极品在线观看| 欧美第一黄网免费网站| www.欧美精品一二三区| 一道本无吗dⅴd在线播放一区| 国产成人亚洲精品| 亚洲成在人线av| 欧美精品激情在线| 91精品国产91久久久久| 色妞一区二区三区| 视频在线观看一区二区| 久久久久久尹人网香蕉| 不用播放器成人网| 欧美日韩中文字幕在线视频| 亚洲综合一区二区不卡| 欧美日韩加勒比精品一区| 欧美日韩亚洲系列| 97香蕉久久超级碰碰高清版| 综合网日日天干夜夜久久| 欧美精品aaa| 欧美性感美女h网站在线观看免费| 久久久久久12| 亚洲精品一区中文| 久久精品99国产精品酒店日本| 欧美亚洲免费电影| 亚洲最大福利视频网| 伦理中文字幕亚洲| 国产丝袜一区视频在线观看| 日本在线观看天堂男亚洲| 亚洲女人被黑人巨大进入| 综合国产在线视频| 一区二区三区视频免费在线观看| 日韩精品中文字幕在线观看| 色小说视频一区| 欧洲成人在线视频| 亚洲第一中文字幕| 久久av在线看| 午夜美女久久久久爽久久| 丝袜情趣国产精品| 日韩电影视频免费| 色系列之999| 日本在线精品视频| 精品久久久久久久久久ntr影视| 亚洲丝袜在线视频| 日韩欧中文字幕| 国产精品一二区| 色噜噜狠狠色综合网图区| 欧美在线影院在线视频| 亚洲网站在线播放| 亚洲精品视频在线播放| 亚洲福利视频网| 日韩美女免费观看| 久久久久久久一区二区三区| 欧美成人在线网站| 97成人精品区在线播放| 成人国产精品色哟哟| 久久久久久久影院| 亚洲色在线视频| 欧美二区乱c黑人| 国语自产偷拍精品视频偷| 亚洲欧洲美洲在线综合| 裸体女人亚洲精品一区| 亚洲精品一区av在线播放| 亚洲国产精品人久久电影| 在线观看久久久久久| 欧美精品少妇videofree| 日韩美女中文字幕| 日韩男女性生活视频| 国产精品久久久999| 最近日韩中文字幕中文| 国产精品久久久久久久久粉嫩av| 97香蕉久久超级碰碰高清版| 国产精品视频一区二区高潮| 日韩欧美在线视频| 国产精品视频区| 久久久中文字幕| 亚洲精品日韩激情在线电影| 欧美成人在线影院| 亚洲天堂男人天堂女人天堂| 国产成人精品优优av| 一区二区亚洲欧洲国产日韩| 最近免费中文字幕视频2019| 91精品久久久久| 欧美久久久精品| 欧美性资源免费| 亚洲第一av网站| 亚洲男人的天堂在线播放| 国产一区二区三区高清在线观看| 亚洲成人亚洲激情| 亚洲第一级黄色片| 亚洲经典中文字幕| 久久久天堂国产精品女人| 亚洲国产精品va在看黑人| 欧美xxxx做受欧美| 午夜精品一区二区三区在线| 成人久久一区二区| 日韩有码片在线观看| 日韩国产激情在线| 在线电影av不卡网址| 性欧美亚洲xxxx乳在线观看| 亚洲第一福利视频| 亚洲精品一区av在线播放| 亚洲天堂av综合网|