2012-04-19 8 views
33

もう1つは、ベストプラクティスですか?私は Odersky、et alによるScalaの本を読んでいます。これは、Collections API関数の多くではインフィクスが使用されていますが、ドットはプログラマ定義の関数用に予約されているようです。スカラ - インフィックス対ドット表記

答えて

43

私は個人的にはこれに対して厳しい規則を持っていませんが、記号的なメソッド名と英数字のドット表記でのみ使用する傾向があります。

コードを挿入すると、後でコードを修正するのが面倒になります。下記は用例です。

あなたはこのコード行を持っている想像:

xs filter { f } map { g } 

は、あなたが最後にtoListを追加する必要がある時間内にいくつかの後者の点であるとします。

xs filter { f } map { g } toList 

これは、セミコロンの推論の問題を引き起こす可能性があります。これらの問題を回避するには、最後にセミコロンを付けるか、新しい行を挿入します。私の意見では、どちらのオプションも醜いです。このナンセンスをすべて避けるために、私はxs.filter(f).map(g)と行くことを好む。この構文では常にリファクタリングが簡単です。

もう一つの例:私は私のコードに次のしていると言う:

if(foo contains bar) { .. 

言って、私は条件を否定する必要があります。私が次のように変更した場合:

if(!foo contains bar) { .. 

バマー。これは、(!foo).contains(bar)として解析されます。私たちが望むものではありません。

それとも、ほかに新しい条件を追加する必要がある、とあなたはそれを修正したとします

if(foo contains bar && cond) { .. 

もうがっかりします。これは、foo.contains(bar.&&(cond))として解析されます。私たちが望んでいたものではありません。

もちろん、かっこを追加することはできますが、ドット表記と比べて見栄えが悪く、読み込み/編集が難しいでしょう。

今、私が上に述べたことのすべては、象徴的なメソッド名にも当てはまります。しかし、シンボリックメソッドはドットシンタックスで使用すると不自然に見えるので、それらのインフィクス構文を好む。


上記のガイドラインの1つの例外:内部DSL。彼らは通常、文書/例(通常は中置表記法を使用している)で規定された方法で書かれたときに、解析の問題を引き起こさないよう注意して作成されます。

+6

この同じロジックは、(オペレータの選択に加えて)優先順位を制御する追加のメカニズムを提供するため、中置表記のために使用することもできます。優先順位をより視覚的に明らかにします。例えば、最初の例を真の関数で書き直してみてください。 '(xs filter f map g).toList'はまだ' xs.filter(f).map(g).toList ) ' –

+2

かっこをかざすには、非線形編集が必要です。挿入記号を避けるもう一つの理由があります。中括弧を破棄しても、このケースには役立ちません。 – missingfaktor

+1

そこにカッコがあります。相対的な "強さ"の演算子と組み合わせて、かっこ/中括弧を使用すると、コードを清潔に保つための強力なツールとして、中置とドットの記法を使用して優先順位を制御する能力があります。 –

12

個人的な好みの問題です。あるスタイルを使用するか他のスタイルを使用するかは、コードを最も読みやすくするものに基づいて決定する必要があります。

ただし、ドットとかっこを切り捨てる機能は、特定の構文構造にのみ制限されるため、時にはそれらを使用することに戻す必要があることに注意してください。

+5

も注意。マイナーな違いですが、それは "最も読みやすい"考察の一部となります。 –

+0

a ??(b)の代わりに?bを使用できますか?あなたはすべてのバイトを保存する必要がある場合b。 :)もちろん、このような名前のメソッドの数は何とか制限されています。 –

2

正式なScalaサイトのドキュメントにドット表記法より適切な使用法表記法が記載されています。style guideがあります。

サフィックス表記:

names.toList 
// is the same as 
names toList // Unsafe, don't use! 

アリティ-1:

// right! 
names foreach (n => println(n)) 
names mkString "," 
optStr getOrElse "<empty>" 
// wrong! 
javaList add item 

高階関数:

// wrong! 
names.map (_.toUpperCase).filter (_.length > 5) 
// right! 
names map (_.toUpperCase) filter (_.length > 5) 

シンボリック方法/演算子:

// right! 
"daniel" + " " + "Spiewak" 
// wrong! 
"daniel"+" "+"spiewak" 
0

mapにインフィックス表記を使用すると、catsライブラリでデカルトを作成しているときにうまく動作することがわかりました。例えば:

(fetchIt(1) |@| fetchIt(2) |@| fetchIt(3)).map(MyCaseClass) 

あなたはそうのような周囲の括弧を取り除くことができます。

fetchIt(1) |@| fetchIt(2) |@| fetchIf(3) map MyCaseClass 

と私の見解では第二の変形はよりよい読み込みます。私が推測する味の問題。ちょうど私の2セントを追加したかったのです。

これは、 "| @ |"の|が、 "map"の中でmより高い優先度を持ちます。詳細はScalaのLANG仕様のこの部分を読む:

式のいくつかの中置演算がある場合、事業者は、優先順位の高い は低く 優先とより密接演算子よりもバインド。 `a.op(b)は` `長い演算B``よりもあるが(オペアンプB) 'よりも短いこと

http://scala-lang.org/files/archive/spec/2.12/06-expressions.html#infix-operations

関連する問題