Scala'da java.String.format nasıl kullanılır?


322

.formatBir dize yöntemi kullanmaya çalışıyorum . Ancak dizeye% 1,% 2 vb. Yerleştirirsem, java.util.UnknownFormatConversionException kafa karıştırıcı bir Java kaynak kodu parçasına işaret ederek atılır:

private void checkText(String s) {

    int idx;

    // If there are any '%' in the given string, we got a bad format
    // specifier.
    if ((idx = s.indexOf('%')) != -1) {
        char c = (idx > s.length() - 2 ? '%' : s.charAt(idx + 1));
        throw new UnknownFormatConversionException(String.valueOf(c));
    }
}

Bundan anladığım kadarıyla %char yasaklanmıştır. Öyleyse, argüman yer tutucuları için ne kullanmalıyım?

Kullandığım Scala 2.8.

Yanıtlar:


302

Önceki tüm yanıtlar doğru olsa da, hepsi Java'dadır. İşte bir Scala örneği:

val placeholder = "Hello %s, isn't %s cool?"
val formatted = placeholder.format("Ivan", "Scala")

Ayrıca yararlı olabilecek Python operatörü gibi yapmaformat% hakkında bir blog yazısı var .


2
JDK belgelerinde çok sayıda örnek: docs.oracle.com/javase/7/docs/api/java/util/…
angelcervera

1
formatDoğrudan dize hazır bilgisine uygulayarak basitleştirebilirsiniz :"Hello %s, isn't %s cool?".format("Ivan", "Scala")
sotrh

298

Konumlandırmayı belirtmek için sayı kullanmanıza gerek yoktur. Varsayılan olarak, bağımsız değişkenin konumu, dizede göründüğü sıradır.

İşte bunu kullanmanın doğru yoluna bir örnek:

String result = String.format("The format method is %s!", "great");
// result now equals  "The format method is great!".

%Yöntemin dizeyi nasıl görüntülemesi gerektiğini bilmesini sağlamak için her zaman onu izleyen başka karakterler kullanacaksınız. %smuhtemelen en yaygın olanıdır ve sadece argümanın dize olarak ele alınması gerektiği anlamına gelir.

Her seçeneği listelemeyeceğim, ancak size bir fikir vermek için birkaç örnek vereceğim:

// we can specify the # of decimals we want to show for a floating point:
String result = String.format("10 / 3 = %.2f", 10.0 / 3.0);
// result now equals  "10 / 3 = 3.33"

// we can add commas to long numbers:
result = String.format("Today we processed %,d transactions.", 1000000);
// result now equals  "Today we processed 1,000,000 transactions."

String.formatsadece a kullanır java.util.Formatter, böylece seçeneklerin tam açıklaması için Formatter javadoc'larını görebilirsiniz .

Ve BalusC'un belirttiği gibi, ihtiyacınız olduğunda varsayılan argüman sırasını değiştirmek mümkün olan belgelerde göreceksiniz. Bununla birlikte, muhtemelen bunu yapmanız gereken / istediğiniz tek zaman, aynı argümanı birden fazla kez kullanıyorsanız.


127

Kaynak koduna bakmak yerine, javadoc String.format () ve Formatter sözdizimini okumalısınız .

% Biçiminden sonra değerin biçimini belirtirsiniz. Örneğin ondalık tam sayı için dve String için s:

String aString = "world";
int aInt = 20;
String.format("Hello, %s on line %d",  aString, aInt );

Çıktı:

Hello, world on line 20

Eğer (bir argüman endeksi kullanın) çalıştığı şey yapmak için, kullanın: *n*$,

String.format("Line:%2$d. Value:%1$s. Result: Hello %1$s at line %2$d", aString, aInt );

Çıktı:

Line:20. Value:world. Result: Hello world at line 20

70

Bunu kullanabilirsiniz;

String.format("%1$s %2$s %2$s %3$s", "a", "b", "c");

Çıktı:

abbc


1
Bu tür bir kullanım hızı hiç görmedim, dize tekrarlandığında çok yararlı, harika!
Domi.Zhang

8
+1 bu daha çok bir C # geliştiricisi olarak kullandığınız gibi. Orada, kullandığımız {0}ve {1}yerine %1$ve %2$.
2699

@ ashes999 Ben de c # karadayım. Unutmuş olduğum parantezleri numaralandırmaya çok alışkınım, bu bir şeyler yapmanın standart yolu değildi. Yüzde işaretlerini görmek her şeyi geri getiriyor!
JonnyRaa

13

Ayrıca Scala'nın String'i bir dizi yöntemle genişlettiğini (Predef tarafından getirilen bir WrappedString'e örtük dönüştürme yoluyla), böylece aşağıdakileri de yapabileceğinizi unutmayın:

val formattedString = "Hello %s, isn't %s cool?".format("Ivan", "Scala")


10

Scala 2.10'da

val name = "Ivan"
val weather = "sunny"

s"Hello $name, it's $weather today!"

1
Bu sadece dize birleştirme özel bir sözdizimi ($ name ve $ weather daha önce tanımlanan değişkenlere zor başvurular olduğu anlamına) alır. Ancak String.Format, şablonu bir parametre olarak alır ve böylece örneğin bir özellikler dosyasından şablonu almayı mümkün kılar. - Yukarıdaki sözdizimiyle bu mümkün mü?
chiccodoro

Bu String dize enterpolasyon, skala içinde iki türü vardır: s "" ve f "", 's' basit dize ve 'f' benzer printf, hatta kendi enterpolasyon tanımlayabilirsiniz (ben değil Deneyin). $nameDeğişkenin değeri ile değiştirin olması gerektiğini araçlar name, aynı zamanda örneğin, interpolasyon işlemi yapabileceğinis"Hello ${name.toUpperCase}, it's $weather today!"
Londo'yu

3

Bu, neler String.formatyapabileceğinizin bir listesidir . Aynısı - için de geçerliprintf

int i = 123;
o.printf( "|%d|%d|%n" ,       i, -i );      // |123|-123|
o.printf( "|%5d|%5d|%n" ,     i, -i );      // |  123| –123|
o.printf( "|%-5d|%-5d|%n" ,   i, -i );      // |123  |-123 |
o.printf( "|%+-5d|%+-5d|%n" , i, -i );      // |+123 |-123 |
o.printf( "|%05d|%05d|%n%n",  i, -i );      // |00123|-0123|

o.printf( "|%X|%x|%n", 0xabc, 0xabc );      // |ABC|abc|
o.printf( "|%04x|%#x|%n%n", 0xabc, 0xabc ); // |0abc|0xabc|

double d = 12345.678;
o.printf( "|%f|%f|%n" ,         d, -d );    // |12345,678000|     |-12345,678000|
o.printf( "|%+f|%+f|%n" ,       d, -d );    // |+12345,678000| |-12345,678000|
o.printf( "|% f|% f|%n" ,       d, -d );    // | 12345,678000| |-12345,678000|
o.printf( "|%.2f|%.2f|%n" ,     d, -d );    // |12345,68| |-12345,68|
o.printf( "|%,.2f|%,.2f|%n" ,   d, -d );    // |12.345,68| |-12.345,68|
o.printf( "|%.2f|%(.2f|%n",     d, -d );    // |12345,68| |(12345,68)|
o.printf( "|%10.2f|%10.2f|%n" , d, -d );    // |  12345,68| | –12345,68|
o.printf( "|%010.2f|%010.2f|%n",d, -d );    // |0012345,68| |-012345,68|

String s = "Monsterbacke";
o.printf( "%n|%s|%n", s );                  // |Monsterbacke|
o.printf( "|%S|%n", s );                    // |MONSTERBACKE|
o.printf( "|%20s|%n", s );                  // |        Monsterbacke|
o.printf( "|%-20s|%n", s );                 // |Monsterbacke        |
o.printf( "|%7s|%n", s );                   // |Monsterbacke|
o.printf( "|%.7s|%n", s );                  // |Monster|
o.printf( "|%20.7s|%n", s );                // |             Monster|

Date t = new Date();
o.printf( "%tT%n", t );                     // 11:01:39
o.printf( "%tD%n", t );                     // 04/18/08
o.printf( "%1$te. %1$tb%n", t );            // 18. Apr


1

@Londo Scala'nın "s" string interpolator'ından bahsetmesine rağmen, Scala'nın "f" string interpolator'ının orijinal soru ile daha alakalı olduğunu düşünüyorum . Diğer yanıtlarda birkaç kez kullanılan örnek de (Scala 2.10'dan beri) şu şekilde yazılabilir:

scala> val name = "Ivan"
name: String = Ivan
scala> val thing = "Scala"
thing: String = Scala
scala> val formatted = f"Hello $name%s, isn't $thing%s cool?"
formatted: String = Hello Ivan, isn't Scala cool?

Orijinal sorunun bağlantısı şu hususların farkında olmalıdır:

  • formatted"f" harfinin önüne bir dize eklenir. Bu "f" (biçimlendirme) dize enterpolatörüdür.
  • "F" string interpolator şunu kullanır: java.util.Formatter
  • java.lang.String.format aynısını kullanır java.util.Formatter

Dize enterpolasyonu ile ilgili güzel şey, hangi değişkenin String.formatmetoda argümanlarla eşleştirilmesi yerine doğrudan dizeye değiştirildiğini görmenize izin vermesidir.


0

Scala olarak, dize Interpolation için elimizdeki $ gün kaydeder ve çok kolay bizim hayat kurmak:

Örneğin: Giriş adını ve yaşını alan, Merhaba adında ve yaşını söyleyen bir işlev tanımlamak istiyorsunuz. Bu şöyle yazılabilir:

def funcStringInterpolationDemo(name:String,age:Int)=s"Hey ! my name is $name and my age is $age"

Bu nedenle, bu işlevi çağırdığınızda: şöyle:

funcStringInterpolationDemo("Shivansh",22)

Çıkışı:

Hey ! my name is Shivansh and my age is 22

Kodu aynı satıra değiştirmek için yazabilirsiniz, sanki yaşınıza 10 yıl eklemek istiyorsanız!

o zaman işlev olabilir:

def funcStringInterpolationDemo(name:String,age:Int)=s"Hey ! my name is $name and my age is ${age+10}"

Ve şimdi çıktı:

Hey ! my name is Shivansh and my age is 32
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.