Öncelik gibi "to" ve "as" yöntem adı önekleri arasındaki fark nedir
- Listeye(),
- asList (),
- vb...
Hangi yöntemi ne zaman kullanmalı?
Öncelik gibi "to" ve "as" yöntem adı önekleri arasındaki fark nedir
Hangi yöntemi ne zaman kullanmalı?
Yanıtlar:
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_tuple
olan, referansla argümanlarını ifade eden biz varız .
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.
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 as
olduğu gibi asString
, asFloat
, asSeconds
ve 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
, array
ve hash
sı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
, asList
vb, 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.
toString
nesneden 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#toArray
ise, Arrays#asList
dö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.
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();
}
}
}
Fark ettim ki fark (şimdi düşünerek)
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:
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.
toString()
?