web-dev-qa-db-ja.com

"to"と "as"メソッド名の接頭辞の違いは何ですか?

"to""as"メソッド名の接頭辞の違いは何ですか

  • toList()、
  • asList()、
  • 等...

メソッドを設計するときにどちらを使用するのですか?

80
Daniel Hári

toXYZ()関数は変換を行い、新しいindependentオブジェクトを返すことが期待されます(不変性により最適化が可能ですが、Java.lang.String.toString()はオブジェクトを返すだけです)。
例として、C++には std::bitset::to_ulong() があり、簡単に失敗する可能性があり、 to_string() が大量にあり、 (多かれ少なかれ)複雑な変換とメモリの割り当て。

一方、asXYZ()関数は、ソースの(潜在的に異なる)ビューを返し、最小限の作業を行うことが期待されています。
例として、C++には、定数参照を返す std::as_const() があり、より複雑な std::forward_as_Tuple は、参照により引数も参照します。

120
Deduplicator

正直なところ、それは単に名前の不一致の可能性があります。たとえば、Smalltalkの標準ライブラリオブジェクトを見ると、「複雑な変換」または「別のタイプの単純な表現を返す」すべてのメソッドには、asasStringasFloatのように、asSecondsが前に付き、何かをその他、as: aClass

Rubyでは、to_to_sto_astringの短縮形、arrayhashのように、同じ種類のメソッドの前にto_hが付いています。

どちらの標準ライブラリも異なる種類の変換を区別しているようには見えません。おそらくそれは実装の詳細と見なされるべきだからです。

ただし、Javaの場合、多くの取り違えが見られます。前述のように、toStringasListなどがあります。これらは名前の不一致にすぎないと思います。各接頭辞の意味が異なる場合、標準ライブラリの別の場所に常に反例が見つかります。

したがって、いずれにしても、重要なことは、あなたとあなたのチームが1つの接頭辞を選択し、コード全体で一貫してそれを使用することです。一貫性が鍵となるので、あなたがそうしなければならなかったように、人々は不思議に思われることはありません。

13
MichelHenrich

すでに受け入れられた回答はありますが、質問はJavaでタグ付けされている一方で、C++に焦点を当てているようです。 Javaでは、この種のことについて最初に頭に浮かぶ例はArrays.asListであり、基本的に、リストにラップされた配列のビューを返します。基になる配列とリストはまだ接続されています。配列への変更はリストに反映され、その逆も同様です。ただし、リストのtoArrayメソッドによって返される配列は、元の配列およびリストから独立しています。

String[] wordArray = {"one", "fine", "day"};
List<String> wordList = Arrays.asList(wordArray);

// changes to the array are visible in the list
System.out.println(wordList); // prints "[one, fine, day]"
wordArray[1] = "horrible";
System.out.println(wordList); // prints "[one, horrible, day]"

// changes to the list are visible in the array
wordList.set(1, "beautiful");
System.out.println(wordArray[1]); // prints "beautiful"

// but changes to the list or array don't affect the 
// result from the list's toArray method.
String[] moreWords = wordList.toArray(new String[] {});
wordList.set(0, "the");
wordArray[1] = "best";
for (int i=0; i<3; i++) {
  System.out.println(moreWords[i]); // prints "one", "beautiful", and "day"
}

とはいえ、すべてのライブラリ開発者がこの規則に従う保証はありません。そのため、ドキュメントを確認して、これが未知のコードから得られる動作であるかどうかを確認する必要があります。

私が見た他の場所as ...()頻繁に使用されるメソッドは、サブタイプへの型のダウンキャストです。たとえば、列挙されたサブタイプのセットがある場合、次のようなコードになる可能性があります。

  /**
   * Every Node is either an ANode or a BNode.
   */
  interface Node {

    /**
     * Returns this Node as an ANode.
     * 
     * @return this node
     */
    default ANode asANode() {
      if (this instanceof ANode) {
        return (ANode) this;
      }
      else {
        throw new UnsupportedOperationException();
      }
      // Or, in Java8 style, perhaps:
      // return Optional.of(this)
      //     .filter(ANode.class::isInstance)
      //     .map(ANode.class::cast)
      //     .orElseThrow(UnsupportedOperationException::new);
    }

    /**
     * Returns this Node as a BNode.
     * 
     * @return this node
     */
    default BNode asBNode() {
      if (this instanceof BNode) {
        return (BNode) this;
      }
      else {
        throw new UnsupportedOperationException();
      }
    }
  }
6
Joshua Taylor

私が気づいた違い(ちょうど今それについて考えたところ)は

  • 通常は別の参照型(やや複雑なオブジェクト)に変換する
  • 通常、単純な値タイプを返します

したがって、AsIntegerとAsStringが表示され、ToArrayとToStringListが表示されます。

意味のある変換(それは運動、プロセス)を意味します。表現を意味するように、元のオブジェクトを表現する方法。

これを見る別の方法:

  • Toは操作なので、メソッドに使用します。
  • は単純な表現なので、プロパティに使用します。

そして、扱う「先行技術」(またはレガシー)があります。言語が完全にOOになるまでは、StrToInt()やIntToStr()などのライブラリ関数がありました。変換を実行するので、それらは操作なので、SomethingToSomethingelse()と呼ぶのが理にかなっています。結局のところ、ToはAsよりもアクティブなので、ここではDelphiについて特に考えています。

C#を設計するときにOOずっと行く意欲があったので、整数を文字列に変換する整数オブジェクトにメソッドを持つことは理にかなっています。クラス、文字列への変換は非常に一般的であるため、オブジェクトの仮想メソッドになりました。設計者は、ToStringが古いパラダイムの人々には馴染みがあると考えているかもしれません。おそらく、これが仮想メソッドToString()を取得した理由ではなく、仮想プロパティAsString。

1
Martin Maat