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.