“To” ve “as” yönteminin adı önekleri arasındaki fark nedir? [kapalı]


78

Öncelik gibi "to" ve "as" yöntem adı önekleri arasındaki fark nedir

  • Listeye(),
  • asList (),
  • vb...

Hangi yöntemi ne zaman kullanmalı?

Yanıtlar:


120

Bir toXYZ()işlevin bir dönüşüm gerçekleştirmesi ve yeni bir bağımsız nesne döndürmesi beklenir (değişmezlik optimizasyona izin verir, java.lang.String.toString()ancak nesneyi döndürür).
Örnek olarak, C ++ std::bitset::to_ulong()'da kolayca başarısız olan ve to_string()hepsinin (az ya da çok) karmaşık bir dönüşümünü yapan ve bellek tahsis eden bir miktar bolluğuna sahibiz .

asXYZ()Öte yandan, bir işlevin, kaynağın (potansiyel olarak farklı) bir görüntüsünü döndürmesi ve minimum iş yapması beklenir.
Bir örnek olarak, C ++ std::as_const()'ta sadece sabit bir referans döndüren ve daha fazla ilgili std::forward_as_tupleolan, referansla argümanlarını ifade eden biz varız .


19
Bunun için bazı emsallerin olduğu ortaya çıktı. Genel olarak, [bir şey] bir alçıya benzeyecek, oysaki [bir şey] mevcut olandan yeni bir nesne (farklı türde) inşa edecek. ToList durumunda, O (n) olacak ve neredeyse kesinlikle "As" dan daha pahalı olacak. Bkz stackoverflow.com/questions/17968469/...
Robert Harvey

5
Tanımlayıcı isimleri seçmenin bir parçasıdır ve bu özel ayrım kodlama standardında kodlanmış olmasa bile, ihlal edilmesi en az şaşkınlık prensibini ihlal eder .
Deduplicator

11
İçgüdüsel olarak, "değiştirmeyi", "değişmeyi" ve "düşünmeyi" olarak "düşünürüm" olarak tanımlardım. İlki, bir şeyi değiştirmek için çalışmayı, ikincisi bunun onunla nasıl çalıştığınızı fark etmesini ifade eder.
Latty

6
Bir anlamı varsa, bunun anlamı olmalı. Ben genellikle bunun bir anlamı olmadığını söylerdim, bu yüzden rastgele üçüncü taraf koduna (dokümanda bir şey görmeden) güvenmezdim. Yine de bir kod tabanında kabul etmek iyi bir kongre olacaktır.
Ben

4
Bu cevap C ++ dilinde de doğrudur: örneğin std::to_string(x), yeni bir dize nesnesi std::as_const(x)yaratır , ancak mevcut nesnenin referansını (görünümü) oluşturur.
Quuxplusone

13

Dürüst olmak gerekirse, sadece tutarsızlığı adlandırmak olabilir. Örneğin Smalltalk standart kütüphane nesneleri, bakmak, "karmaşık dönüşümler" veya "başka tür basit temsillerini dönüş" do tüm yöntemler öneki ise asolduğu gibi asString, asFloat, asSecondsve her şeyden bir şey dönüştürmek için standart yöntem as: aClass.

Ruby, yöntem aynı türde öneki to_gibi to_s, to_a, to_h, kısa string, arrayve hashsırasıyla.

Her iki standart kitaplık da farklı türdeki dönüşümler arasında ayrım yapmaz, çünkü muhtemelen bir uygulama detayı olarak görülmelidir.

Bununla birlikte, Java'da çok fazla karışıklık görüyoruz. Eğer belirtildiği gibi, orada toString, asListvb, vb. Bunların sadece bir adlandırma tutarsızlığı olduğuna inanıyorum, çünkü her önek için farklı bir anlam tanımlamaya çalışırsanız, standart kütüphanede her zaman başka bir yerde bir karşı örnek bulacaksınız.

Her halükarda, önemli bir şeyin sizin ve ekibinizin bir önek seçip kod boyunca tutarlı bir şekilde kullanması olduğunu söyleyebilirim. Tutarlılık anahtardır, bu yüzden insanlar sizin yaptığınız gibi merak etmeye bırakılmaz.


1
Buna inanmıyorum: tüm ekip için bir stil seçmek, bir modülde benzer durumlar için bir stil seçmek, sürekli olarak.
Daniel Hári

12
Java'da, toStringnesneden tamamen ayrılmış yeni bir dize oluşturur (ve değişmezlik nedeniyle başka bir yol yoktur). Aynı örneğin tutan için Collection#toArrayise, Arrays#asListdöner çift yönlü olarak bağlı olan bir dizi, bir görünüşüdür (dizi mutasyona listesini ve tersi değiştirir). Bu nedenle istisnalar olsa da oldukça tutarlı. Bir ön ek seçmek yanlış olur. Olsaydı Arrays#toList, yeni bir temel diziyle yeni bir liste oluşturmasını beklerdim.
maaartinus

Bence Smalltalk orada bir hata yaptı, sözleşmeyi anlamadı. Anlamak (ve hatta farketmek) zor bir kongre çünkü çok soyut ve özellikle etkili değil. Bu soruyu sorma hareketi bile içgörü gerektirir.
usr

3
@ usr Smalltalk bir kongre haline gelmeden önce dizayn edilmiş olabilir
Bergi

6

Zaten kabul edilmiş bir cevap olmasına rağmen, soru java ile etiketlenirken C ++ 'a odaklanılmış gibi görünüyor . Java'da, bu tür bir şey için akla gelen ilk örnek , temelde listeye sarılmış bir dizinin görünümünü döndüren Arrays.asList'tir . Temel dizi ve liste yine de birbirine bağlı; dizideki değişiklikler listeye yansıtılır ve bunun tersi de geçerlidir. Ancak, listenin toArray yöntemi tarafından döndürülen dizi , orijinal diziden ve listeden bağımsızdır:

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"
}

Bununla birlikte, her kitaplık geliştiricisinin bu sözleşmeyi izlemesi garantisi yoktur, bu nedenle, bilinmeyen koddan alacağınız davranış olup olmadığını öğrenmek için belgelere bakmanız gerekir.

Gördüğüm diğer yer ... () metodu sık kullanılan, alt tiplere yapılan downcasting tipleri. Örneğin, numaralandırılmış bir alt tür kümeniz varsa, aşağıdaki gibi bir kodla bitebilirsiniz:

  /**
   * 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();
      }
    }
  }

1

Fark ettim ki fark (şimdi düşünerek)

  • Genellikle farklı bir referans türüne (biraz karmaşık bir nesne) dönüştürür
  • Tipik olarak basit bir değer tipi döndürür

Böylece AsInteger ve AsString'i görüyoruz ve ToArray ve ToStringList'i görüyoruz.

Mantıklı olan bir dönüşümü ima etmek (bir harekettir, bir süreçtir). Bir temsili ima ettiği gibi, orijinal nesneyi ifade etmenin bir yolu.

Buna bakmak için başka bir yol:

  • Olmak bir işlem, bu yüzden yöntemler için kullanırdın.
  • Basit bir temsil olduğu gibi özellikleri için de kullanırsınız.

Ve sonra başa çıkmak için "önceki sanat" (veya eski) var. Dilleri tamamen sıfırdan önce, StrToInt () ve IntToStr () gibi kütüphane fonksiyonlarına sahip olacaksınız. Dönüşümler yaptılar, operasyonlardı, bu yüzden onları SomethingToSomethingelse () olarak adlandırmak mantıklıydı. Ne de olsa, Kime As'dan daha aktif. Özellikle Delphi'yi burada düşünüyorum.

C #, OO'ya tamamen gitmek istemi ile tasarlandığında, şimdi tamsayı nesnesinde tamsayıyı dizeye dönüştürecek bir yönteme sahip olmak mantıklı geliyordu. Ayrıca bir Convert sınıfımız olmasına rağmen, dizgeye dönüştürme işlemi, nesnede sanal bir yöntem haline getirildiği kadar yaygındır. Tasarımcılar, ToString'in eski paradigmadan insanlara daha aşina olacağını ve belki de sanal bir AsString değil sanal ToString () yönteminin bulunmasının nedeni olduğunu düşünmüş olabilirler.


3
Ne hakkında toString()?
Deduplicator

Beni yakaladın. Bence AsString daha uygun olurdu. Bazı düşünceler ekleyelim, cevabımı güncelleyeceğim.
Martin Maat,

Bu cevabın C # 'daki sözleşmelere gerçekten yaklaştığını sanmıyorum. Örneğin. ToList () ve AsEnumerable () her ikisi de karmaşık nesneleri döndürür, fark ise ToList () her zaman yeni bir nesne döndürürken, AsEnumerable () orijinal nesnenin üzerinde bir görünüm veya bağdaştırıcı verir.
JacquesB

@JaquesB Anlaşılan burada ve orada farklı fikirler var. Delphi, TField nesnelerinde (veritabanı alanlarını kapsayan) AsInteger ve AsString özelliklerine sahiptir. Bunun için önyargılı olabilirdim. Ama sonra tekrar, soru C # ya da Delphi ile değil, Java ile etiketlenir.
Martin Maat
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.