2013-04-25 30 views
16

Với Delphi XE4 cho nền tảng iOS, một kiểu chuỗi mới đã được giới thiệu: Chuỗi không dựa trên không thay đổi. Cho đến nay Delphi đã có bản sao viết các chuỗi có thể thay đổi được. Vì vậy, câu hỏi là, điều đó có ý nghĩa gì đối với chương trình tương lai của tôi? Có lợi thế của một loại chuỗi trên khác không? Những cạm bẫy tôi cần phải chăm sóc khi chuyển sang loại chuỗi mới (Khác với cơ sở 0 vs 1 rõ ràng) là gì?Delphi XE4 chuỗi bất biến

+0

Lưu ý rằng đây là trình chuyển đổi trình biên dịch nếu các chuỗi không dựa trên. Chắc chắn không phải là một ý tưởng tốt để kết hợp cả hai cách nhưng ít nhất bạn có thể tự quyết định khi nào để thực hiện quá trình chuyển đổi. – jpfollenius

+0

Chúng ta phải sử dụng lớp 'TStringBuilder' để thao tác chuỗi và' TStringHelper' để xử lý chuỗi chung. –

+0

Kiểu 'String' thực sự giống như trước, nó chỉ là toán tử' [] 'bị ảnh hưởng. Tính không thay đổi đơn giản có nghĩa là trình biên dịch không cho phép một 'Char' được gán cho toán tử và chỉ thị' {$ ZEROBASEDSTRINGS} 'chỉ ảnh hưởng đến cách trình biên dịch diễn giải các chỉ mục được truyền cho toán tử. Bản thân loại 'String' không được thiết kế lại. –

Trả lời

17

Theo Marco Cantù's whitepaper, loại dữ liệu string trong mục tiêu XE4 iOS không thực sự bất biến, mặc dù có vẻ như mâu thuẫn với bản thân.

Ông nói:

Trong trình biên dịch mới Delphi LLVM dựa trên, có một loại chuỗi, đại diện chuỗi Unicode (UTF16), và ánh xạ tới các loại chuỗi hiện nay ở Delphi XE3 (một bí danh cho Loại UnicodeString trên trình biên dịch Windows). Tuy nhiên, loại chuỗi mới này sử dụng một mô hình quản lý bộ nhớ khác. Kiểu chuỗi vẫn là tham chiếu được tính, nhưng nó không thay đổi, có nghĩa là bạn không thể sửa đổi nội dung chuỗi khi nó được xây dựng.

Nhưng sau đó ông tiếp tục nói:

Nói cách khác chuỗi hiện nay Unicode-based, sắp trở thành bất biến, và tài liệu tham khảo-tính.

Và cũng:

đâu mọi thứ bắt đầu thay đổi, tuy nhiên, là khi bạn sửa đổi một chuỗi đang tồn tại, chứ không phải bằng cách thay thế nó bằng một giá trị mới (trong trường hợp này bạn sẽ có được một thương hiệu mới string) nhưng khi bạn thay đổi một trong những yếu tố của nó, như thể hiện trong dòng mã này (và cũng có thể trong phần trước, nơi tôi giới thiệu chủ đề):

Str1 [3] := 'x'; 

Tất cả các trình biên dịch Delphi sử dụng ngữ nghĩa copy-on-write: Nếu chuỗi bạn sửa đổi có nhiều tham chiếu, nó được sao chép lần đầu tiên (điều chỉnh số lượng tham chiếu của các chuỗi khác nhau liên quan theo yêu cầu) và sửa đổi sau này.

Trình biên dịch mới thực hiện điều gì đó rất giống với trình biên dịch cổ điển. Nó thực hiện một cơ chế sao chép khi viết, trừ khi có một tham chiếu duy nhất cho chuỗi, trong trường hợp đó chuỗi được sửa đổi ở địa chỉ . Ví dụ, hãy xem xét mã sau đây, sẽ xuất ra vị trí trong bộ nhớ của chuỗi thực tế.

Và sau đó, anh ấy sẽ hiển thị ảnh của thiết bị iOS có chuỗi đột biến.

Và trong official documentation ta có:

Strings là không thay đổi (thường xuyên), vì vậy bạn không thể chỉ vào một chuỗi như một mảng và thao tác các ký tự trong một chuỗi. Nếu bạn cố gắng để sửa đổi một chuỗi, trình biên dịch di động Delphi có thể phát ra thông báo W1068 Chuỗi sửa đổi tại chỗ có thể không được hỗ trợ trong tương lai (Delphi).Bạn có thể chỉ định xem thông báo x1068 có được phát ra là cảnh báo hoặc lỗi hay không. Trong trang Gợi ý và cảnh báo, hãy đặt cảnh báo "Sửa đổi chuỗi tại chỗ ...." thành "true" hoặc "error".

Vì vậy, tôi giải thích tất cả những điều đó có nghĩa là bản phát hành XE4 của trình biên dịch iOS vẫn có chuỗi có thể thay đổi. Các nhà phát triển thực sự không muốn bạn thay đổi chuỗi của bạn nữa và nói với bạn rằng các chuỗi không thay đổi được trên các trình biên dịch di động. Nhưng chúng vẫn xuất hiện để có thể thay đổi được. Đi con số!


Tuy nhiên, bạn đã được thông báo trước rằng trong bản phát hành sau, chuỗi có thể trở nên không thay đổi.

Bạn có thể chuẩn bị cho rằng phát hành trong tương lai bây giờ bằng cách thiết lập

{$WARN IMMUTABLE_STRINGS WARN} 

mà sẽ cung cấp cho bạn một ý tưởng về tác động của sự thay đổi. Nếu bạn muốn khóa và ngừng các chuỗi thay đổi, bạn có thể thực hiện việc này:

{$WARN IMMUTABLE_STRINGS ERROR} 

Khi bạn làm điều đó, bạn sẽ cần phải chuyển đổi mã truy cập các phần tử chuỗi riêng lẻ. Tôi nghi ngờ bạn sẽ ngạc nhiên bởi ít mã như vậy. Tôi vừa biên soạn 600.000 dòng mã và chỉ thấy 120 trường hợp cảnh báo. Và hầu hết trong số đó là các đơn vị của bên thứ ba. Tôi đã nhìn thấy khá khuấy động về sự thay đổi này, nhưng tôi thành thật không tin rằng rất nhiều mã biến đổi chuỗi. Trong phần lớn các trường hợp, chuỗi được tạo ra bằng cách nối hoặc gọi tới các hàm như Format. Mã đó không bị ảnh hưởng bởi điều này.

Tôi không nghĩ có bất kỳ cạm bẫy lớn nào. Bạn có thể sử dụng {$WARN IMMUTABLE_STRINGS ...} để cho trình biên dịch hướng dẫn bạn qua quy trình. Bất kỳ mã nào thay đổi chuỗi phải được chuyển đổi để sử dụng TStringBuilder.

Đối với những lợi ích về tính bất biến, tôi giới thiệu bạn đến Why .NET String is immutable?

Nếu bạn đang sử dụng trình biên dịch Windows hoặc OSX truyền thống thì tôi thấy không có lý do thuyết phục để thay đổi. Trình biên dịch iOS hoàn toàn mới. Sự thay đổi các chuỗi bất biến đã được thả nổi, nhưng nó có thể không bao giờ xảy ra. Nó có thể xảy ra chỉ trên các trình biên dịch di động và không bao giờ trên các trình biên dịch truyền thống. Ngay bây giờ, tôi sẽ ngồi thật chặt và đợi xem tất cả diễn ra như thế nào.

+3

Tim Anderson cũng bị nhầm lẫn về cách bất biến chuỗi di động bất biến mới thực sự là: http://www.itwriting.com/blog/7347-changes-in-the-delphi-language-for-arm-and-mobile- support.html –

+3

Woah, tôi hơi e ngại khi chuyển sang kết luận nhưng điều này nghe có vẻ như một ý tưởng tồi khác của các nhà phát triển Delphi. Hãy phá vỡ khả năng tương thích để làm cho chuỗi hữu ích hơn, kế hoạch tuyệt vời. – himself

+3

@himself Có những lợi ích với bất biến. Và trong mọi trường hợp, đó là một thay đổi tác động rất thấp. Bỏ qua các thư viện của bên thứ ba mà người khác sẽ giải quyết, tôi có thể sửa mã nguồn của tôi trong khoảng một giờ.Tôi thà rằng một số của các cruft của ngôn ngữ đã được gỡ bỏ, ngay cả khi nó có nghĩa là một số đau về phía chúng tôi. –

Các vấn đề liên quan