string.format với các biến so với biến nội tuyến


9

Những ưu / nhược điểm (nếu có) để sử dụng là gì

string output; 
int i = 10;
output = string.Format("the int is {0}", i);

đấu với

string output; 
int i = 10;
output = "the int is " + i;

Tôi đã luôn sử dụng ví dụ sau, nhưng có vẻ như phần lớn các hướng dẫn trực tuyến sử dụng ví dụ string.format. Tôi không nghĩ rằng có bất kỳ sự khác biệt thực sự nào về hiệu quả, suy nghĩ ban đầu của tôi là vì vậy một lập trình viên không phải tiếp tục phá vỡ chuỗi để chèn các biến.


8
Lý do chính là nó làm cho việc dịch thuật dễ dàng hơn nhiều, bởi vì chương trình của bạn không cần phải hiểu cách các ngôn ngữ khác nhau xây dựng câu của họ. Ví dụ, nhiều thành ngữ và cụm từ trong tiếng Pháp là từ trước đến sau so với bản dịch tiếng Anh của họ.
JohnL

Câu trả lời:


22

Nếu bạn coi dịch thuật là quan trọng trong dự án của bạn, cú pháp đầu tiên sẽ thực sự giúp ích cho nó.

Chẳng hạn, bạn có thể có:

static final string output_en = "{0} is {1} years old.";
static final string output_fr = "{0} a {1} ans.";

int age = 10;
string name = "Henri";
System.out.println(string.Format(output_en, name, age));
System.out.println(string.Format(output_fr, name, age));

Cũng lưu ý rằng các biến của bạn có thể không luôn luôn ở cùng một vị trí trong câu với cú pháp đó:

static final string output_yoda = "{1} years {0} has.";

4
+1 để sử dụng Yoda-speak làm ví dụ về cú pháp đối tượng-chủ ngữ-động từ.
Mike Harris

1
Với C #, chúng tôi có một tùy chọn mới:System.out.println($"{name} is {age} year's old.");
Berin Loritsch


@BerinLoritsch: thật không thể sử dụng để bản địa hóa, thật không may.
Bryan Boettcher

@BryanBoettcher, đã hiểu, nhưng tôi không thấy bất cứ điều gì trong OP nói rằng đó là những gì họ đang cố gắng thực hiện.
Berin Loritsch

8

Kiểm tra câu trả lời đầu tiên cho /programming/4671610/why-use-opes-format . Nó bao gồm mọi thứ theo ý kiến ​​của tôi là tại sao nó tốt hơn.

Ngoài ra, mỗi hội đồng .NET có một nhóm thực tập, chứa một tập hợp các chuỗi duy nhất. Khi mã của bạn được biên dịch, tất cả các chuỗi ký tự bạn tham chiếu trong mã của bạn sẽ được thêm vào nhóm này. Nếu bạn có một mã trông như thế này:

"the int is " + i + " and the double is " + d

Điều đó làm cho nó 2 chuỗi trong hồ bơi.

Nếu bạn có:

"the int is {0} and the double is {1}"

Bạn chỉ có một Chuỗi trong nhóm.

Sẽ phức tạp hơn một chút khi biết khi nào String được thực tập và khi nào thì không phải vì trình biên dịch có một số thông minh khi phát hiện ra các chuỗi có thể không cần phải được thực hiện đôi khi ... Hãy xem ví dụ bài viết này để hiểu rõ hơn về điều này vấn đề.

Chỉnh sửa: sau khi đào lên một chút, tôi đã gặp một câu trả lời thú vị cho câu hỏi Khi nào nên sử dụng String.Format vs chuỗi kết hợp? . Nói tóm lại, tác giả của câu trả lời với hơn 30 phiếu bầu đưa ra một lập luận thuyết phục có lợi cho nối chuỗi khi không liên quan đến nội địa hóa.


2
Tôi cũng nghĩ, theo phong cách, nó cộng hưởng với những người như những người như tôi, những người đã quen với printf và sprintf từ c.
Jonathan Henson

Tôi muốn biết lý do tại sao downvote để sửa câu trả lời của tôi. Cảm ơn.
Jalayn

4

Tôi thích cách đầu tiên vì nó cho phép tôi thấy chính xác chuỗi sẽ trông như thế nào khi đầu ra. Rất dễ quên để thêm một khoảng trắng hoặc để thêm khoảng cách bổ sung khi chỉ nối thêm chuỗi.

Tôi chắc chắn rằng cũng có một lợi ích hiệu suất theo cách đầu tiên do không phải tạo các chuỗi bổ sung; nhưng đó không phải là mối quan tâm chính của tôi


2

Bằng cách sử dụng tùy chọn đầu tiên, bạn có thể lưu trữ một chuỗi định dạng thường được sử dụng và giảm việc nhập cần thiết và giúp cập nhật chuỗi ở mọi nơi được sử dụng dễ dàng hơn. Về cơ bản, tùy chọn đầu tiên cho phép DRY được thực hiện dễ dàng. Nó cũng là một cú pháp đẹp hơn nhiều nếu nhiều biến cần được sử dụng trong một chuỗi, như bạn đã đề cập.


ahh tôi hiểu rồi, tôi đoán là tôi đã không nghĩ đến ví dụ: string.format ("int là {0}. một lần nữa nó là {0}", int);
Jim

1

Tôi nghĩ với string.Format()việc dễ dàng hơn để xem chính xác kết quả sẽ như thế nào (vì vậy bạn không gặp vấn đề với không gian bị lãng quên hoặc điều gì đó tương tự), và cũng dễ dàng hơn để nhập và sửa đổi.

Nếu bạn muốn thực hiện định dạng rất đơn giản, sử dụng +toán tử cộng có thể dễ dàng hơn, nhưng tôi có xu hướng chỉ sử dụng nó khi nối hai chuỗi, không nhiều hơn.

Để chỉ ra cách string.Format()dễ dàng sửa đổi hơn, hãy xem xét rằng bạn muốn thêm một điểm dừng hoàn toàn vào cuối câu trong ví dụ của bạn: đi từ string.Format("The int is {0}", i)đến string.Format("The int is {0}.", i)chỉ là một ký tự. Nhưng đi từ "the int is " + iđến "the int is " + i + '.'là nhiều hơn nữa.

Một ưu điểm khác string.Format()là nó cho phép bạn dễ dàng chỉ định định dạng để sử dụng, như thế nào string.Format("The int is 0x{0:X}.", i). Điều này thậm chí còn quan trọng hơn khi định dạng ngày.

Đối với hiệu quả, string.Format()rất có thể là chậm hơn mà nối chuỗi đơn giản. Nhưng mã như thế này rất có thể không phải là một con đường nóng, vì vậy nó không thành vấn đề. Và nếu có, có lẽ bạn nên sử dụng StringBuilder.


chuỗi.Format bên trong sử dụng StringBuilder
Bryan Boettcher

1

Sử dụng một trong đó làm cho mã của bạn dễ đọc nhất. Đừng lo lắng về hiệu suất.

Ví dụ của bạn dưới đây tôi thích B vì nó dễ đọc hơn. Nhưng các bản dịch ngôn ngữ ở trên cũng có ý nghĩa. Đừng để bất cứ ai ép buộc bạn sử dụng chuỗi.Format, thay vào đó hãy đọc và chỉ vào blog tuyệt vời của Jeff Atwoods trên The Sad Tragedy of Micro Optimifying Theater

A:

string output; 
int i = 10;
output = string.Format("the int is {0}", i);

đấu với

B:

string output; 
int i = 10;
output = "the int is " + i;

-1

Tham chiếu: Đầu ra chuỗi: định dạng hoặc concat trong C #?

Hãy xem xét mã này.

Đây là một phiên bản sửa đổi một chút của mã của bạn.

  1. Tôi đã xóa Console.WriteLine vì nó có thể chậm hơn vài bậc so với những gì tôi đang cố gắng đo.
  2. Tôi đang nhìn đồng hồ bấm giờ trước vòng lặp và dừng ngay sau đó, theo cách này tôi sẽ không mất độ chính xác nếu chức năng lấy ví dụ 26,4 tick để thực thi.
  3. Cách bạn chia kết quả theo số lần lặp là sai. Xem những gì bản lề nếu bạn có 1000 mili giây và 100 mili giây. Trong cả hai tình huống, bạn sẽ nhận được 0 ms sau khi chia cho 1000000.
Stopwatch s = new Stopwatch();

var p = new { FirstName = "Bill", LastName = "Gates" };

int n = 1000000;
long fElapsedMilliseconds = 0, fElapsedTicks = 0, cElapsedMilliseconds = 0, cElapsedTicks = 0;

string result;
s.Start();
for (var i = 0; i < n; i++)
    result = (p.FirstName + " " + p.LastName);
s.Stop();
cElapsedMilliseconds = s.ElapsedMilliseconds;
cElapsedTicks = s.ElapsedTicks;
s.Reset();
s.Start();
for (var i = 0; i < n; i++)
    result = string.Format("{0} {1}", p.FirstName, p.LastName);
s.Stop();
fElapsedMilliseconds = s.ElapsedMilliseconds;
fElapsedTicks = s.ElapsedTicks;
s.Reset();


Console.Clear();
Console.WriteLine(n.ToString()+" x result = string.Format(\"{0} {1}\", p.FirstName, p.LastName); took: " + (fElapsedMilliseconds) + "ms - " + (fElapsedTicks) + " ticks");
Console.WriteLine(n.ToString() + " x result = (p.FirstName + \" \" + p.LastName); took: " + (cElapsedMilliseconds) + "ms - " + (cElapsedTicks) + " ticks");
Thread.Sleep(4000);

Đó là kết quả của tôi:

1000000 x result = string.Format("{0} {1}", p.FirstName, p.LastName); took: 618ms - 2213706 ticks
1000000 x result = (p.FirstName + " " + p.LastName); took: 166ms - 595610 ticks

1
Làm thế nào điều này trả lời các khía cạnh của nếu ví dụ mã đầu tiên hoặc ví dụ mã thứ hai là một thiết kế tốt hơn? Làm thế nào để một nửa giây trên 1M lặp lại tài khoản cho nếu đây là mã dễ dàng hơn cho một người để duy trì hay không?

Jim hỏi, "những ưu và nhược điểm là gì?" Điều này cho thấy qua nhiều lần lặp lại, String.Format nhanh hơn.
jp2code

Bạn nên xem xét bổ sung đầy đủ vào câu trả lời của mình thay vì để nó dưới dạng một khối mã và sự khác biệt so với mã của OP. Vì thế, câu trả lời của bạn không trả lời câu hỏi của OP bằng tiếng Anh. Nhìn vào các câu trả lời khác. Có thể xóa tất cả mã khỏi chúng và vẫn có câu trả lời cho câu hỏi của OP.
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.