Có phải là cách thực hành tốt hơn để sử dụng String.format trên Ghép chuỗi trong Java?


273

Có sự khác biệt rõ ràng nào giữa việc sử dụng String.formatvà nối chuỗi trong Java không?

Tôi có xu hướng sử dụng String.formatnhưng đôi khi sẽ trượt và sử dụng nối. Tôi đã tự hỏi nếu một trong những tốt hơn so với người khác.

Cách tôi nhìn thấy nó, String.formatcung cấp cho bạn nhiều sức mạnh hơn trong việc "định dạng" chuỗi; và ghép nối có nghĩa là bạn không phải lo lắng về việc vô tình bỏ thêm% s hoặc bỏ lỡ.

String.format cũng ngắn hơn

Cái nào dễ đọc hơn phụ thuộc vào cách bạn làm việc.


Tôi nghĩ rằng chúng ta có thể đi với MessageFormat.format. Vui lòng xem câu trả lời stackoverflow.com/a/56377112/1491414 để biết thêm thông tin.
Ganesa Vijayakumar

Câu trả lời:


242

Tôi đề nghị rằng nó là thực hành tốt hơn để sử dụng String.format(). Lý do chính là String.format()có thể dễ dàng bản địa hóa hơn với văn bản được tải từ các tệp tài nguyên trong khi ghép nối không thể được bản địa hóa mà không tạo ra một tệp thực thi mới với mã khác nhau cho mỗi ngôn ngữ.

Nếu bạn dự định ứng dụng của mình có thể bản địa hóa, bạn cũng nên tập thói quen chỉ định vị trí đối số cho mã thông báo định dạng của mình:

"Hello %1$s the time is %2$t"

Điều này sau đó có thể được bản địa hóa và có các mã thông báo tên và thời gian được hoán đổi mà không yêu cầu biên dịch lại tệp thực thi để tính toán cho các thứ tự khác nhau. Với các vị trí đối số, bạn cũng có thể sử dụng lại cùng một đối số mà không cần chuyển nó vào hàm hai lần:

String.format("Hello %1$s, your name is %1$s and the time is %2$t", name, time)

1
Bạn có thể chỉ cho tôi một số tài liệu nói về cách làm việc với các vị trí / thứ tự đối số trong Java (nghĩa là làm thế nào để tham chiếu các đối số theo vị trí của chúng) không? Cảm ơn.
markvgti

13
Muộn còn hơn không, phiên bản Java ngẫu nhiên: docs.oracle.com/javase/1.5.0/docs/api/java/util/ chủ
Aksel

174

Về hiệu suất:

public static void main(String[] args) throws Exception {      
  long start = System.currentTimeMillis();
  for(int i = 0; i < 1000000; i++){
    String s = "Hi " + i + "; Hi to you " + i*2;
  }
  long end = System.currentTimeMillis();
  System.out.println("Concatenation = " + ((end - start)) + " millisecond") ;

  start = System.currentTimeMillis();
  for(int i = 0; i < 1000000; i++){
    String s = String.format("Hi %s; Hi to you %s",i, + i*2);
  }
  end = System.currentTimeMillis();
  System.out.println("Format = " + ((end - start)) + " millisecond");
}

Các kết quả thời gian như sau:

  • Ghép = 265 mili giây
  • Định dạng = 4141 mili giây

Do đó, ghép nối nhanh hơn nhiều so với String.format.


15
Họ đều là thực hành xấu. Sử dụng StringBuilder.
Amir Raminfar

8
StringBuilder nằm ngoài phạm vi ở đây (câu hỏi của OP là về việc so sánh String.format với Ghép chuỗi) nhưng bạn đã thực hiện dữ liệu về String Builder chưa?
Icaro

108
@AmirRaminar: Trình biên dịch tự động chuyển "+" thành các cuộc gọi đến StringBuilder.
Martin Schröder

40
@ MartinSchröder: Nếu bạn chạy javap -c StringTest.classbạn sẽ thấy rằng những người cải biên dịch "+" để StringBuilder tự động chỉ nếu bạn đang không ở trong một vòng lặp. Nếu việc ghép hoàn toàn được thực hiện trên một dòng thì nó cũng giống như sử dụng '+', nhưng nếu bạn sử dụng myString += "morechars";hoặc myString += anotherString;trên nhiều dòng, bạn sẽ nhận thấy rằng nhiều hơn một StringBuilder có thể được tạo, vì vậy sử dụng "+" không phải lúc nào cũng hiệu quả như StringBuilder.
ccpizza

7
@Joffrey: điều tôi muốn nói là các vòng lặp +không được chuyển đổi thành StringBuilder.append()mà thay vào đó new StringBuilder()xảy ra trên mỗi lần lặp.
ccpizza

39

Vì có cuộc thảo luận về hiệu suất, tôi cho rằng tôi sẽ thêm vào một so sánh bao gồm StringBuilder. Thực tế nó nhanh hơn concat và, tùy chọn String.format.

Để làm cho điều này trở thành một loại táo so sánh táo, tôi khởi tạo một StringBuilder mới trong vòng lặp chứ không phải bên ngoài (điều này thực sự nhanh hơn so với việc thực hiện chỉ một lần khởi tạo có khả năng do việc phân bổ lại không gian cho phần bổ sung vòng lặp ở cuối một người xây dựng).

    String formatString = "Hi %s; Hi to you %s";

    long start = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++) {
        String s = String.format(formatString, i, +i * 2);
    }

    long end = System.currentTimeMillis();
    log.info("Format = " + ((end - start)) + " millisecond");

    start = System.currentTimeMillis();

    for (int i = 0; i < 1000000; i++) {
        String s = "Hi " + i + "; Hi to you " + i * 2;
    }

    end = System.currentTimeMillis();

    log.info("Concatenation = " + ((end - start)) + " millisecond");

    start = System.currentTimeMillis();

    for (int i = 0; i < 1000000; i++) {
        StringBuilder bldString = new StringBuilder("Hi ");
        bldString.append(i).append("; Hi to you ").append(i * 2);
    }

    end = System.currentTimeMillis();

    log.info("String Builder = " + ((end - start)) + " millisecond");
  • 2012-01-11 16: 30: 46.058 INFO [TestMain] - Định dạng = 1416 mili giây
  • 2012-01-11 16: 30: 46.190 INFO [TestMain] - Ghép = 134 mili giây
  • 2012-01-11 16: 30: 46.313 INFO [TestMain] - Trình tạo chuỗi = 117 mili giây

21
Kiểm tra StringBuilder không gọi toString (), vì vậy đây không phải là một so sánh công bằng. Tôi nghi ngờ bạn sẽ thấy nó nằm trong lỗi đo lường hiệu suất của phép nối nếu bạn sửa lỗi đó.
Jamey Sharp

15
Trong các bài kiểm tra định dạng và nối, bạn đã yêu cầu a String. Thử nghiệm StringBuilder, để công bằng, cần một bước cuối cùng để biến nội dung của StringBuilder thành Chuỗi. Bạn làm điều đó bằng cách gọi bldString.toString(). Tôi hy vọng điều đó giải thích nó?
Jamey Sharp

4
Jamey Sharp hoàn toàn chính xác. Gọi bldString.toString () là như nhau nếu không chậm hơn so với nối chuỗi.
Akos Cz

3
String s = bldString.toString(); Timings là với nối và StringBuilder gần như ngang bằng với nhau: Format = 1520 millisecond, Concatenation = 167 millisecond, String Builder = 173 millisecond tôi chạy chúng trong một vòng lặp và trung bình mỗi ra để có được một đại diện tốt: (tối ưu hóa trước JVM, sẽ cố gắng một vòng lặp Trên 10000 khi tôi nhận được thời gian)
TechTrip

3
Làm thế nào để các bạn thậm chí biết thời tiết mã được thực thi? Các biến không bao giờ được đọc hoặc sử dụng, bạn không thể chắc chắn rằng JIT không xóa mã này ở vị trí đầu tiên.
alobodzk

37

Một vấn đề với .formatlà bạn mất an toàn loại tĩnh. Bạn có thể có quá ít đối số cho định dạng của mình và bạn có thể có các loại sai cho các chỉ định định dạng - cả hai đều dẫn đến IllegalFormatException thời gian chạy , do đó bạn có thể kết thúc bằng mã đăng nhập phá vỡ sản xuất.

Ngược lại, các đối số +có thể được kiểm tra bởi trình biên dịch.

Các lịch sử an ninh của(trên đó formatchức năng được mô hình hóa) là dài và đáng sợ.


16
chỉ để ghi lại, các IDE hiện đại (ví dụ IntelliJ) hỗ trợ số lượng đối số và loại đối sánh
Ron Klein

2
Điểm hay về biên dịch, tôi khuyên bạn nên thực hiện các kiểm tra này thông qua FindBugs (có thể chạy trong IDE hoặc qua Maven trong quá trình xây dựng), lưu ý rằng điều này cũng sẽ kiểm tra định dạng trong tất cả nhật ký của bạn! Điều này hoạt động bất kể người dùng IDE
Barshe Roussy

20

Cái nào dễ đọc hơn phụ thuộc vào cách bạn làm việc.

Bạn đã có câu trả lời của bạn ngay tại đó.

Đó là vấn đề sở thích cá nhân.

Việc nối chuỗi là nhanh hơn một chút, tôi cho rằng, nhưng điều đó không đáng kể.


3
Tôi đồng ý. Suy nghĩ về sự khác biệt hiệu suất ở đây chủ yếu chỉ là tối ưu hóa sớm - trong trường hợp không chắc chắn rằng hồ sơ cho thấy có vấn đề ở đây, sau đó lo lắng về nó.
Jonik

3
Đó thực sự chỉ là vấn đề sở thích cá nhân nếu dự án nhỏ và không bao giờ có ý định quốc tế hóa theo bất kỳ ý nghĩa nào. Mặt khác, String.format chiến thắng trong việc ghép nối theo mọi cách.
workmad3

4
Tôi không đồng ý. Cho dù dự án có lớn đến đâu, bạn cũng khó có thể bản địa hóa mọi chuỗi được xây dựng trong đó. Nói cách khác, nó phụ thuộc vào tình huống (các chuỗi được sử dụng để làm gì).
Jonik

Tôi không thể tưởng tượng bất cứ ai sẽ coi 'String.format ("% s% s", a, b)' dễ đọc hơn 'a + b' và đưa ra sự khác biệt về tốc độ theo thứ tự câu trả lời dường như rõ ràng với tôi (trong các tình huống sẽ không yêu cầu nội địa hóa như gỡ lỗi hoặc hầu hết các báo cáo đăng nhập).
BobDoolittle

16

Đây là một thử nghiệm với nhiều kích cỡ mẫu tính bằng mili giây.

public class Time {

public static String sysFile = "/sys/class/camera/rear/rear_flash";
public static String cmdString = "echo %s > " + sysFile;

public static void main(String[] args) {

  int i = 1;
  for(int run=1; run <= 12; run++){
      for(int test =1; test <= 2 ; test++){
        System.out.println(
                String.format("\nTEST: %s, RUN: %s, Iterations: %s",run,test,i));
        test(run, i);
      }
      System.out.println("\n____________________________");
      i = i*3;
  }
}

public static void test(int run, int iterations){

      long start = System.nanoTime();
      for( int i=0;i<iterations; i++){
          String s = "echo " + i + " > "+ sysFile;
      }
      long t = System.nanoTime() - start;   
      String r = String.format("  %-13s =%10d %s", "Concatenation",t,"nanosecond");
      System.out.println(r) ;


     start = System.nanoTime();       
     for( int i=0;i<iterations; i++){
         String s =  String.format(cmdString, i);
     }
     t = System.nanoTime() - start; 
     r = String.format("  %-13s =%10d %s", "Format",t,"nanosecond");
     System.out.println(r);

      start = System.nanoTime();          
      for( int i=0;i<iterations; i++){
          StringBuilder b = new StringBuilder("echo ");
          b.append(i).append(" > ").append(sysFile);
          String s = b.toString();
      }
     t = System.nanoTime() - start; 
     r = String.format("  %-13s =%10d %s", "StringBuilder",t,"nanosecond");
     System.out.println(r);
}

}

TEST: 1, RUN: 1, Iterations: 1
  Concatenation =     14911 nanosecond
  Format        =     45026 nanosecond
  StringBuilder =      3509 nanosecond

TEST: 1, RUN: 2, Iterations: 1
  Concatenation =      3509 nanosecond
  Format        =     38594 nanosecond
  StringBuilder =      3509 nanosecond

____________________________

TEST: 2, RUN: 1, Iterations: 3
  Concatenation =      8479 nanosecond
  Format        =     94438 nanosecond
  StringBuilder =      5263 nanosecond

TEST: 2, RUN: 2, Iterations: 3
  Concatenation =      4970 nanosecond
  Format        =     92976 nanosecond
  StringBuilder =      5848 nanosecond

____________________________

TEST: 3, RUN: 1, Iterations: 9
  Concatenation =     11403 nanosecond
  Format        =    287115 nanosecond
  StringBuilder =     14326 nanosecond

TEST: 3, RUN: 2, Iterations: 9
  Concatenation =     12280 nanosecond
  Format        =    209051 nanosecond
  StringBuilder =     11818 nanosecond

____________________________

TEST: 5, RUN: 1, Iterations: 81
  Concatenation =     54383 nanosecond
  Format        =   1503113 nanosecond
  StringBuilder =     40056 nanosecond

TEST: 5, RUN: 2, Iterations: 81
  Concatenation =     44149 nanosecond
  Format        =   1264241 nanosecond
  StringBuilder =     34208 nanosecond

____________________________

TEST: 6, RUN: 1, Iterations: 243
  Concatenation =     76018 nanosecond
  Format        =   3210891 nanosecond
  StringBuilder =     76603 nanosecond

TEST: 6, RUN: 2, Iterations: 243
  Concatenation =     91222 nanosecond
  Format        =   2716773 nanosecond
  StringBuilder =     73972 nanosecond

____________________________

TEST: 8, RUN: 1, Iterations: 2187
  Concatenation =    527450 nanosecond
  Format        =  10291108 nanosecond
  StringBuilder =    885027 nanosecond

TEST: 8, RUN: 2, Iterations: 2187
  Concatenation =    526865 nanosecond
  Format        =   6294307 nanosecond
  StringBuilder =    591773 nanosecond

____________________________

TEST: 10, RUN: 1, Iterations: 19683
  Concatenation =   4592961 nanosecond
  Format        =  60114307 nanosecond
  StringBuilder =   2129387 nanosecond

TEST: 10, RUN: 2, Iterations: 19683
  Concatenation =   1850166 nanosecond
  Format        =  35940524 nanosecond
  StringBuilder =   1885544 nanosecond

  ____________________________

TEST: 12, RUN: 1, Iterations: 177147
  Concatenation =  26847286 nanosecond
  Format        = 126332877 nanosecond
  StringBuilder =  17578914 nanosecond

TEST: 12, RUN: 2, Iterations: 177147
  Concatenation =  24405056 nanosecond
  Format        = 129707207 nanosecond
  StringBuilder =  12253840 nanosecond

1
StringBuilder hoàn toàn là phương pháp nhanh nhất khi bạn nối các ký tự trong một vòng lặp, ví dụ, khi bạn muốn tạo một chuỗi với một nghìn 1 bằng cách thêm từng ký tự một. Dưới đây là thông tin thêm: pellegrino.link/2015/08/22/ Kẻ
Carlos Hoyos

Tôi thích nó như thế nào bạn luôn sử dụng String.format cho đầu ra: D vì vậy có một lợi thế. và thành thật mà nói nếu chúng ta không nói về hàng triệu lần lặp, tôi thích string.format vì dễ đọc vì mã của bạn cho thấy lợi thế rõ ràng!
mohamnag

9

Đây là thử nghiệm tương tự như trên với việc sửa đổi cách gọi phương thức toString () trên StringBuilder . Các kết quả dưới đây cho thấy cách tiếp cận StringBuilder chỉ chậm hơn một chút so với cách ghép chuỗi bằng toán tử + .

tệp: StringTest.java

class StringTest {

  public static void main(String[] args) {

    String formatString = "Hi %s; Hi to you %s";

    long start = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++) {
        String s = String.format(formatString, i, +i * 2);
    }

    long end = System.currentTimeMillis();
    System.out.println("Format = " + ((end - start)) + " millisecond");

    start = System.currentTimeMillis();

    for (int i = 0; i < 1000000; i++) {
        String s = "Hi " + i + "; Hi to you " + i * 2;
    }

    end = System.currentTimeMillis();

    System.out.println("Concatenation = " + ((end - start)) + " millisecond");

    start = System.currentTimeMillis();

    for (int i = 0; i < 1000000; i++) {
        StringBuilder bldString = new StringBuilder("Hi ");
        bldString.append(i).append("Hi to you ").append(i * 2).toString();
    }

    end = System.currentTimeMillis();

    System.out.println("String Builder = " + ((end - start)) + " millisecond");

  }
}

Các lệnh Shell: (biên dịch và chạy StringTest 5 lần)

> javac StringTest.java
> sh -c "for i in \$(seq 1 5); do echo \"Run \${i}\"; java StringTest; done"

Các kết quả :

Run 1
Format = 1290 millisecond
Concatenation = 115 millisecond
String Builder = 130 millisecond

Run 2
Format = 1265 millisecond
Concatenation = 114 millisecond
String Builder = 126 millisecond

Run 3
Format = 1303 millisecond
Concatenation = 114 millisecond
String Builder = 127 millisecond

Run 4
Format = 1297 millisecond
Concatenation = 114 millisecond
String Builder = 127 millisecond

Run 5
Format = 1270 millisecond
Concatenation = 114 millisecond
String Builder = 126 millisecond

6

String.format()không chỉ là chuỗi nối. Ví dụ: bạn có thể hiển thị số trong một ngôn ngữ cụ thể bằng cách sử dụng String.format().

Tuy nhiên, nếu bạn không quan tâm đến nội địa hóa, không có sự khác biệt về chức năng. Có thể cái này nhanh hơn cái kia, nhưng trong hầu hết các trường hợp, nó sẽ không đáng kể ..


4

Nói chung, nối chuỗi nên được ưu tiên hơn String.format. Cái sau có hai nhược điểm chính:

  1. Nó không mã hóa chuỗi được xây dựng theo cách cục bộ.
  2. Quá trình xây dựng được mã hóa thành một chuỗi.

Đến điểm 1, ý tôi là không thể hiểu String.format()cuộc gọi đang làm gì trong một lần chuyển tiếp. Người ta buộc phải qua lại giữa chuỗi định dạng và đối số, trong khi đếm vị trí của các đối số. Đối với các kết nối ngắn, đây không phải là một vấn đề nhiều. Tuy nhiên, trong những trường hợp này, nối chuỗi ít dài dòng hơn.

Theo điểm 2, ý tôi là phần quan trọng của quy trình xây dựng được mã hóa theo chuỗi định dạng (sử dụng DSL). Sử dụng chuỗi để biểu diễn mã có nhiều nhược điểm. Nó không phải là loại an toàn vốn có, và làm phức tạp việc làm nổi bật cú pháp, phân tích mã, tối ưu hóa, v.v.

Tất nhiên, khi sử dụng các công cụ hoặc khung bên ngoài ngôn ngữ Java, các yếu tố mới có thể phát huy tác dụng.


2

Tôi chưa thực hiện bất kỳ điểm chuẩn cụ thể nào, nhưng tôi nghĩ rằng việc ghép có thể nhanh hơn. String.format () tạo ra một Formatter mới, lần lượt, tạo ra một StringBuilder mới (với kích thước chỉ 16 ký tự). Đó là một lượng chi phí khá lớn, đặc biệt nếu bạn định dạng một chuỗi dài hơn và StringBuilder tiếp tục phải thay đổi kích thước.

Tuy nhiên, ghép nối ít hữu ích và khó đọc hơn. Như mọi khi, đáng để thực hiện một điểm chuẩn trên mã của bạn để xem cái nào tốt hơn. Sự khác biệt có thể không đáng kể trong ứng dụng máy chủ sau khi các gói tài nguyên, địa phương, v.v. của bạn được tải trong bộ nhớ và mã bị JITted.

Có lẽ là một cách thực hành tốt nhất, sẽ là một ý tưởng tốt để tạo Formatter của riêng bạn với StringBuilder (Appendable) và Locale có kích thước phù hợp và sử dụng nó nếu bạn có nhiều định dạng để làm.


2

Có thể có một sự khác biệt dễ nhận biết.

String.format khá phức tạp và sử dụng một biểu thức chính quy bên dưới, vì vậy đừng tạo thói quen sử dụng nó ở mọi nơi, mà chỉ ở nơi bạn cần.

StringBuilder sẽ là một trật tự cường độ nhanh hơn (như ai đó ở đây đã chỉ ra).


1

Tôi nghĩ rằng chúng ta có thể đi với MessageFormat.format vì nó phải tốt cả về khả năng đọc và cả khía cạnh hiệu suất.

Tôi đã sử dụng cùng một chương trình mà Icaro đã sử dụng trong câu trả lời ở trên của anh ấy và tôi đã cải tiến nó bằng mã nối thêm để sử dụng MessageFormatđể giải thích các số hiệu suất.

  public static void main(String[] args) {
    long start = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++) {
      String s = "Hi " + i + "; Hi to you " + i * 2;
    }
    long end = System.currentTimeMillis();
    System.out.println("Concatenation = " + ((end - start)) + " millisecond");

    start = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++) {
      String s = String.format("Hi %s; Hi to you %s", i, +i * 2);
    }
    end = System.currentTimeMillis();
    System.out.println("Format = " + ((end - start)) + " millisecond");

    start = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++) {
      String s = MessageFormat.format("Hi %s; Hi to you %s", i, +i * 2);
    }
    end = System.currentTimeMillis();
    System.out.println("MessageFormat = " + ((end - start)) + " millisecond");
  }

Ghép = 69 mili giây

Định dạng = 1435 mili giây

MessageFormat = 200 mili giây

CẬP NHẬT:

Theo Báo cáo SonarLint, các chuỗi định dạng kiểu Printf nên được sử dụng đúng cách (mực: S3457)

Vì các printf-stylechuỗi định dạng được diễn giải trong thời gian chạy, thay vì xác thực bởi trình biên dịch, chúng có thể chứa các lỗi dẫn đến các chuỗi sai được tạo. Quy tắc này tĩnh xác nhận mối tương quan của printf-stylechuỗi định dạng để lập luận của mình khi gọi các phương pháp định dạng (...) của java.util.Formatter, java.lang.String, java.io.PrintStream, MessageFormat, và java.io.PrintWritercác lớp học và các printf(...)phương pháp java.io.PrintStreamhoặc java.io.PrintWritercác lớp học.

Tôi thay thế kiểu printf bằng dấu ngoặc nhọn và tôi nhận được kết quả thú vị như dưới đây.


Định dạng liên kết = 69 mili giây Định dạng = 1107 mili giây
Định dạng: xoăn-ngoặc = 416 mili giây
MessageFormat = 215 mili giây
MessageFormat: xoăn-ngoặc = 2517 mili giây

Kết luận của tôi:
Như tôi đã nhấn mạnh ở trên, sử dụng String.format với dấu ngoặc nhọn sẽ là một lựa chọn tốt để có được lợi ích về khả năng đọc tốt và hiệu suất.


0

Bạn không thể so sánh Chuỗi nối và Chuỗi.Format theo chương trình trên.

Bạn có thể thử điều này cũng sẽ thay đổi vị trí sử dụng String.Format và Ghép trong khối mã của bạn như dưới đây

public static void main(String[] args) throws Exception {      
  long start = System.currentTimeMillis();

  for( int i=0;i<1000000; i++){
    String s = String.format( "Hi %s; Hi to you %s",i, + i*2);
  }

  long end = System.currentTimeMillis();
  System.out.println("Format = " + ((end - start)) + " millisecond");
  start = System.currentTimeMillis();

  for( int i=0;i<1000000; i++){
    String s = "Hi " + i + "; Hi to you " + i*2;
  }

  end = System.currentTimeMillis();
  System.out.println("Concatenation = " + ((end - start)) + " millisecond") ;
}

Bạn sẽ ngạc nhiên khi thấy rằng Format hoạt động nhanh hơn ở đây. Điều này là do các đối tượng nội bộ được tạo có thể không được phát hành và có thể có vấn đề với việc cấp phát bộ nhớ và do đó hiệu suất.


3
bạn đã thử mã của bạn chưa? Sự kết hợp luôn nhanh hơn mười lần
Icaro

những gì về millis được thực hiện để thực hiện "System.cienTimeMillis ()": P.
Rehan

0

Phải mất một ít thời gian để làm quen với String.Format, nhưng nó đáng giá trong hầu hết các trường hợp. Trong thế giới của NRA (không bao giờ lặp lại bất cứ điều gì), việc giữ các tin nhắn được mã hóa (ghi nhật ký hoặc người dùng) của bạn trong thư viện Constant là vô cùng hữu ích (tôi thích số tiền nào cho một lớp tĩnh) và gọi chúng là cần thiết với String.Format bất kể bạn là ai đang nội địa hóa hay không. Cố gắng sử dụng một thư viện như vậy với phương pháp nối là khó đọc hơn, khắc phục sự cố, hiệu đính và quản lý với bất kỳ phương pháp nào yêu cầu ghép nối. Thay thế là một lựa chọn, nhưng tôi nghi ngờ đó là hiệu suất. Sau nhiều năm sử dụng, vấn đề lớn nhất của tôi với String.Format là độ dài của cuộc gọi kéo dài một cách bất tiện khi tôi chuyển nó sang một chức năng khác (như Msg), nhưng thật dễ dàng để sử dụng chức năng tùy chỉnh để phục vụ như một bí danh .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.