Swift-style-guide: 関数とメソッド

作成日 2015年07月06日  ·  26コメント  ·  ソース: raywenderlich/swift-style-guide

ガイドは、書くときの関数とメソッドの適切な使用法について明確にする必要があります。 AppleのSwiftプログラミング言語のドキュメントを見てみると、次のようなものです。

メソッドは、クラス、構造体、または列挙型に関連付けられている関数です。 これは、インスタンスメソッドとタイプメソッドの両方に当てはまります。 一方、関数はグローバルスコープで宣言されており、どのタイプにも属していません。

十分でしょう。

最も参考になるコメント

このようなものはどうですか:

メソッドとフリー関数

メソッドはタイプに関連付けられた関数であり、オートコンプリートで検出できるため優先されます。 無料の関数はあまり一般的ではありませんが、操作が特定のタイプまたはインスタンスに密接に関連付けられていない場合は意味があります。

優先

let sorted = items.mergeSort()  // easily discoverable
rocket.launch()  // a mutating method

好ましくない

let sorted = mergeSort(items)
launch(&rocket)

無料の関数例外

let tuples = zip(a, b)  // feels natural as a free function (symmetry)
let value = max(x,y,z)  // another free function that feels natural

全てのコメント26件

「フリー関数」と呼ばれる関数も見ました。 「無料」とは「オブジェクトに関連付けられていない」という意味だと思います。

Swiftでは、関数にはタイプやグローバルよりも多くのスコープオプションがあります。

私はただの通常のメソッドと仮定Objective-C今と呼ばれたfunctionaSwift 。 フォーラム、ブログ、チュートリアルなどに関して私が読んだすべての資料では、クラスまたは列挙型に属している場合でも、それらを単にfunctionsと呼んでいます。

@mitchellporter Apple自身のドキュメントは、上記の引用のように、いつ何かを関数またはメソッドと呼ぶべきかについて明確にしています。

raywenderlich.comのチュートリアルも、ここでAppleのガイドラインに従っています。そのため、スタイルガイドに組み込む必要があります。

Objective-Cにも関数とメソッドの両方があります。 すべてが方法というわけではありません。 😉

@micpringle理にかなっていますが、クラスに属している場合でも、単にfunctionと呼ばれる資料をたくさん読んだことを誓います。 常にfunctionを使用しているのは私だけではないと思いますが、これが今後変化するかどうかを確認するのは興味深いことです。

メソッド内の「funcs」は「ネストされたメソッド」ですか?
クロージャ内の関数または他の非関数とは何ですか?

struct Struct {
   let closure = {
      func whoAmI() {}
   }

   var any: Any? {
      func jeanValjean() {}
      return nil
   }
}

これらは技術的には何にも「属さない」ため、匿名関数(IMO)として分類され、その特定のスコープ内にのみ存在し、その範囲外からアクセスすることはできないと思います。

ここでは「無名関数」が正しい名前だとは思いません—通常はクロージャを指します。

名前付きの型やインスタンスにアタッチされたメソッドではなく、関数であるため、これらを「ネストされた関数」と呼びます。 そして「ネスト」されているのは...ネストされているからです! 「スコープ関数」かもしれませんが、それはそれほど明確ではないようです。

申し訳ありませんが、クロージャが無名関数とも呼ばれていることに気づきませんでした。 :]

入れ子関数は私にはいいですね。 私は、スコープが完全に正しく聞こえないことに同意します。

メソッドであろうとなかろうと、何かの中にある「入れ子関数」は、予見可能な将来には十分明確に思えます。

また、名前を持つ入れ子関数はそれらを「匿名」にすると思いますが、正確に「匿名」とは何かはわかりません。ただし、クロージャ、特に関数に非常によく似た、格納された不変のクロージャについてはわかりません。 私は、格納された関数が実際に匿名であると信じることに傾いていますが、それをキャプチャするクロージャ、および場合によってはいくつかの状態が名前を持っています。 これがC#で教えられている方法です。ラムダ構文は、デリゲートと呼ばれるものを構築するための省略形です。
https://msdn.microsoft.com/en-us/library/system.delegate(v = vs.110).aspx

func nonymous() {
   func nonymous() {}
}

let anonymouses: [() -> ()] = [].map
{$0} // This "transform" is also anonymous.

let unlcearToMeWhetherNonymous = {}

それは微妙な点であり、Swiftの腸に降りると、おそらく議論の余地があります。すべてが同じですが、 func何かを宣言すると、間違いなくその名前が付けられます。 対照的に、クロージャは名前のないコードのブロックです。 もちろん、それを変数または定数に割り当てることもできますが、それは単にモノへのポインターを格納しているだけです。

繰り返しますが、それは一種の人為的な違いです。 あなたはすべてLispのようで、 funcはクロージャに名前を付けるための単なる構文糖衣であると言うことができます。

このようなものはどうですか:

メソッドとフリー関数

メソッドはタイプに関連付けられた関数であり、オートコンプリートで検出できるため優先されます。 無料の関数はあまり一般的ではありませんが、操作が特定のタイプまたはインスタンスに密接に関連付けられていない場合は意味があります。

優先

let sorted = items.mergeSort()  // easily discoverable
rocket.launch()  // a mutating method

好ましくない

let sorted = mergeSort(items)
launch(&rocket)

無料の関数例外

let tuples = zip(a, b)  // feels natural as a free function (symmetry)
let value = max(x,y,z)  // another free function that feels natural

それにかんする、

無料の関数例外

let tuples = zip(a, b)  // feels natural as a free function (symmetry)
let value = max(x,y,z)  // another free function that feels natural

「自然に感じる」はかなり曖昧で主観的です。

ここで私たちが何を意味するのかを明確にできますか?

また、 zipmax両方で、PRで提起した// hard to discover問題が発生します。

私見、 zipは厄介な例だと思います。 私が抱えている問題:

  • それは実際に何をしているのですか? abを組み合わせる? どういうわけかab圧縮しますか? 他に何かありますか? より多くの文脈がなければ、知ることは困難です。

それ以外の

無料の関数はあまり一般的ではありませんが、操作が特定のタイプまたはインスタンスに密接に関連付けられていない場合は意味があります。

これはどう?

クラスや型に関連付けられていない無料の関数は、慎重に使用する必要があります。 可能であれば、free関数の代わりにメソッドを使用することをお勧めします。 これは、読みやすさと発見可能性に役立ちます。

無料の関数は、特定のタイプまたはインスタンスに関連付けられていない場合に最も適しています。

Free Function Exceptionsについてさらに議論するために、この問題を再開します。

さて、これは標準ライブラリ関数です。 R、Python、C#、C ++などの言語で優先されます(ブースト経由)。

さて、これは標準ライブラリ関数です。

本当に? iOSでは使用していません... *困惑*

私はそれをチェックします...それがiOSで広く理解され/使用されているなら、多分ここでの私の懸念は見当違いです...

私はあなたの言い回しの提案が好きです...私はzipの例をあきらめたくありません。 (追記:RW Swiftチームには、iOSよりも大きい(または小さい)憲章があります。)

RW Swiftチームには、iOSよりも大きい(または小さい)憲章があります。

👍本当です。 ;]

zipの機能を確認した後、例として残して

ここで私のSwift-newbie-momentの経験についてお詫びします。 😉

心配ない。 いつものようにあなたの助けをありがとう。 ところで、私はあなたがクレジットに記載されていないことに気づきました。 私もそれを修正します。

無料の関数がこれまでで最高のソリューションであるかどうかはわかりません。 それらを使用する場合は、他の場所では対処されていない機能を追加する必要があると思います。

最大

let max = Swift.max(0, 1, 2)
let maxElement = [0, 1, 2].maxElement()!

maxElementはメソッドではなくプロパティである必要がありますが、それでもfree関数は冗長であると思います。 これらが同じものにコンパイルされない場合は、コンパイラを改善する必要があると思いますが、そうでない場合でも、パフォーマンスは重要ではないと思います。 多くの要素でmax関数を使用する人はいないと思います。

ジップ
C#では、zipはSwiftプロトコル拡張メソッドと同等に実装されています。 それが良いとは思いませんが、これはzip別の方法で処理する方法の例です。

Swiftでは、 zipZip2Sequenceこの初期化子と同じものです。 可変数の入力シーケンスのzipシーケンスを表現する方法があると便利ですが、それが発生するまでは、初期化子を直接使用することで問題ないと思います。

zip([1...3], ["a"..."c"])
Zip2Sequence([1...3], ["a"..."c"])

演算子
私がSwiftで書いた無料の関数の大部分は演算子です。 ChrisLattnerとJoeGroffが、将来的にはC#のような型内で演算子を定義できるようになることを示唆しているのを見てきました。そのため、演算子は、他の関数について、選択された規則に従うこともできるかもしれません。 free-function-onlyとしての現在の実装は、おそらくガイドラインとして使用されるべきではありません。

演算子
私がSwiftで書いた無料の関数の大部分は演算子です。 ChrisLattnerとJoeGroffが、将来的にはC#のような型内で演算子を定義できるようになることを示唆しているのを見てきました...

はい、これはおそらくSwiftが将来進む方向です。 あなたが言ったように、これはクリス・ラトナーからのかなり最近の提案です。

これは、 Equatableようなプロトコルに特に特有であり、拡張ガイドラインに従って、基本的に空の拡張を作成する必要があります。 これはせいぜい厄介です。 😞

私は、演算子が理想的なフリー関数の例として使用されるべきではないことに間違いなく同意します。

コメントありがとうございます@ Jessy-!

いくつかのメモ:

maxElement()はO(1)ではないため、メソッドとして宣言されていると思います。これは一部のユーザーにとっては驚くべきことです。 O(1)以外のプロパティを実装する場合は、明確に文書化する必要があります。 (RWチュートリアルでは、すべてのコードが公開されているという贅沢があるため、スタイルガイドラインとしてそれほど心配したり、強制したりする必要はありません。)

一方、 max<T: Comparable>一部の形式はO(1)であり、ハードウェアを活用するために特化される可能性があります。 (確認はしていませんが、可変個引数バージョンに加えて、2つのパラメーターバージョンがあるのはそのためだと思います。)

いずれにせよ、無料の関数は控えめに使用する必要があることに私たちは皆同意していると思いますが、私は_決して_に反対します。 使用されている例は、標準ライブラリからのものです。 zip関数を標準ライブラリから削除する提案は見たことがありません。 @ JRG-Developerの言い換え、またはこの言い換えを法として現在マージされているプルリクエストの詳細に異議はありますか?

さらに話し合う必要があると思われる場合は、お気軽に再開してください。 (更新ブランチにマージされました。)

このページは役に立ちましたか?
0 / 5 - 0 評価