2015-10-06 45 views
4

嵌套函數的實際用途是什麼?它只會使代碼更難閱讀,並且不會使特定情況變得簡單。swift中嵌套函數的實際用法是什麼?

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 
} 

Source

+1

你是說,相比封閉? – rintaro

+0

你有檢查我的答案嗎? –

+0

是的,我期待更多的答案。您將展示如何使用此功能。我在問如何「使用它」。如果您實際使用的項目中有代碼的一部分,這對我理解這個概念會更有幫助。謝謝 – Esqarrouth

回答

0

在您的例子,你可以創建一個variable這也是function這樣的:

var myStepFunction = chooseStepFunction(true) 

myStepFunction(4) 

嵌套函數的好處是非常好的。例如,假設您正在構建一個應用程序的計算器,你可以有你的邏輯在一個函數,如下所示:

func doOperation(operation: String) -> ((Double, Double) -> Double)? { 
    func plus(s: Double, d: Double) -> Double { 
     return s + d 
    } 
    func min(s: Double, d: Double) -> Double{ 
     return s - d 
    } 
    switch operation { 
     case "+": 
      return plus 
    case "-" : 
     return min 
    default : 
     return nil 
    } 
} 

var myOperationFunction = doOperation("-")?(4, 4) // 0 
var myOperationFunction2 = doOperation("+")?(4, 5) //9 

在某些情況下,你不允許看到的實施一些功能,或對他們不負責。然後將它們隱藏在其他函數內真的是一個好方法。例如,假設你的同事有責任開發plusmin函數,他/她會這樣做,而你只是使用外部函數。

它不同於關閉,因爲在clouser中,將你的邏輯傳遞給其他邏輯,它會調用你的邏輯。這是一種插件。例如,在調用http請求後,您可以傳遞您希望應用程序在接收服務器響應時所要執行的代碼。

+2

爲什麼不只是使用私人功能?你用func(「+」)?(4,5)的例子真是醜陋難懂。這些都不是很好的實際用途,因爲我認爲這個任務會以其他方式更好地完成 – Esqarrouth

+0

@Esqarrouth更好的是,只需使用閉包或eeeeven,直接使用'(+)'或'( - )'作爲閉包 – Alexander

1

一個用例是對遞歸數據結構的操作。

考慮,例如,該代碼在二叉搜索樹搜索:

func get(_ key: Key) -> Value? { 
    func recursiveGet(cur: Node) -> Value? { 
     if cur.key == key { 
      return cur.val 
     } else if key < cur.key { 
      return cur.left != nil ? recursiveGet(cur: cur.left!) : nil 
     } else { 
      return cur.right != nil ? recursiveGet(cur: cur.right!) : nil 
     } 
    } 

    if let root = self.root { 
     return recursiveGet(cur: root) 
    } else { 
     return nil 
    } 
} 

當然,你可以將遞歸成一個圈,用嵌套函數做了。不過,我發現遞歸代碼通常比迭代變體更清晰。 (交易性與運行成本!)

你也可以定義爲recursiveGet(私有)成員的get外面但是這將是糟糕的設計(除非recursiveGet在多種方法中使用)。

0

原理(自Objective-C開始)「代碼可以是數據」。您可以傳遞代碼,將其存儲在變量中,並將其與其他代碼結合使用。這是一個極其有用的工具。坦率地說,如果我沒有能力將代碼當作數據處理,那麼我寫的大多數代碼將難以寫十次,難以閱讀十次。

Swift中的函數只是閉包,所以嵌套函數非常有意義,因爲這是您在不想使用衆多可用快捷鍵之一時編寫閉包的方式。

3

我認爲你的問題的核心是:爲什麼不使用私有函數而不是醜陋的嵌套函數?

簡單地說,嵌套函數可以帶來更多可讀性封裝

私有函數仍然可以從其他功能在你的類訪問。嵌套函數也是如此。你告訴你的開發者,這隻屬於這個函數(與私有函數相反,它們屬於整個類)。退後一步,不要亂它,如果你需要類似的能力,去寫你自己的!

另一個便利是它可以通過訪問所有本地參數到它的父函數。你不再需要通過左右。這將最終意味着少了一個功能測試,因爲你裹了進去另一個

一個功能,當你在你的班上有非常相似的功能,另一種使用情況是,說像你這樣:

extractAllHebrewNames() // right to left language 
extractAllAmericanNames() // left to right language 
extractAllJapaneseNames() // top to bottom language 

現在,如果您有一個名爲printName的私有函數(打印名稱),那麼如果您根據語言切換案例,那麼該函數將起作用,但如果您不這樣做,則會發生什麼。相反,您可以在每個獨立的提取功能中編寫自己的嵌套函數*並打印名稱。

你的問題有點類似,爲什麼不使用'if else'而不是'Switch case'。

我認爲這只是一個提供的便利(對於可以在不使用嵌套函數的情況下處理的東西)。


*:他們現在都可以有完全相同的名稱。因爲每個都位於不同的名稱空間中。

相關問題