Có sự khác biệt giữa các kiểu truyền và chuyển đổi trong các ngôn ngữ lập trình mệnh lệnh không?


8

Câu hỏi được đưa ra trong một cuộc thảo luận tại StackOverflow.

Có một sự phân biệt rõ ràng giữa hai khái niệm đúcchuyển đổi (liên quan đến loại đối tượng), hoặc hai từ này mô tả chính xác giống nhau? Còn các ngôn ngữ khác ngoài C ++, Python và Java thì sao? EDIT : Nếu các loại trong câu hỏi là loại nguyên thủy, như intđể float?

Câu trả lời:


5

Về mặt lý thuyết , hai khái niệm này rất khác nhau:

Kiểu Đúc dùng để trao đổi một loại (nói đại khái là cấu trúc đối tượng) cho loại khác trong khi Chuyển đổi loại liên quan đến dịch các giá trị (nói đại khái là nội dung của đối tượng), do đó chúng có thể được hiểu là thuộc về loại mới. Về mặt lý thuyết, chúng không bao giờ trộn lẫn .

Điều đó nói rằng, thực tế mà nói , trong khi bạn có thể có cái này mà không có cái khác, thì hầu như luôn luôn là một ý tưởng tồi. Rất hiếm khi thay đổi nhận thức của bạn về cấu trúc của một đối tượng, mà không thay đổi nội dung của nó. Thực tế, chúng hầu như luôn giống nhau


3
Điều này thậm chí còn thú vị hơn với một ngôn ngữ được gõ yếu, như C, bạn có thể chỉ cần xem một phần của bộ nhớ là một loại khác!
Sheldon Warkentin

Đó không phải là cách các thuật ngữ "diễn viên" và "chuyển đổi" được sử dụng trong C. Xem câu trả lời của tôi.
Keith Thompson

Tôi đã chỉnh sửa câu hỏi. Bạn có suy nghĩ gì về điều đó không? Cảm ơn!
krlmlr

Câu trả lời không thay đổi đối với người nguyên thủy.
quả việt quất

"Rất hiếm khi thay đổi nhận thức của bạn về cấu trúc của một đối tượng, mà không thay đổi nội dung của nó." Đây không phải là toàn bộ quan điểm của phân nhóm và đa hình sao? giữ một tham chiếu đến một AbstractSpritelúc mà không có ý tưởng nào về việc nó thực sự là một BigGreenTreeSprite?
sara

3

Các ngôn ngữ khác nhau định nghĩa các từ "diễn viên" và "chuyển đổi" khác nhau; Tôi không nghĩ rằng câu hỏi có ý nghĩa khác hơn là liên quan đến một ngôn ngữ cụ thể.

Ví dụ, trong C, thuật ngữ "cast" chỉ đề cập đúng đến một toán tử cast rõ ràng, bao gồm một tên loại trong ngoặc đơn trước biểu thức được chuyển đổi. "Chuyển đổi" chuyển đổi giá trị của một loại thành giá trị của loại khác; một số chuyển đổi được thực hiện bằng cách diễn giải lại các bit tạo nên biểu diễn, nhưng nó được định nghĩa là chuyển đổi giá trị thành giá trị. (Vâng, điều đó đúng ngay cả đối với chuyển đổi con trỏ; các loại con trỏ khác nhau có thể có các cách biểu diễn khác nhau.)

Lưu ý rằng không có thứ gọi là "diễn viên ngầm" trong C.

Một số chuyển đổi là rõ ràng, được chỉ định bởi một nhà điều hành đúc. Các trường hợp khác là ẩn và được áp dụng trong một số trường hợp nhất định khi một biểu thức của một loại được sử dụng trong ngữ cảnh cần một biểu thức của một loại khác. Việc chuyển đổi được thực hiện hoàn toàn giống nhau trong cả hai trường hợp.

Ví dụ:

double x = 1.23;
int y = (int)x;  /* A cast, or explicit conversion, setting y to 1 */
int z = x;       /* An implicit conversion, setting z to 1. */

C ++ cũng tương tự; nó có phôi và chuyển đổi tương tự như C, và nó cho biết thêm một ký hiệu chức năng tương đương với một biểu hiện dàn diễn viên C-phong cách, cộng với 4 từ khóa cụ thể hơn: const_cast, dynamic_cast, reinterpret_cast, và static_cast.


Tôi có phải là người duy nhất không thích truyền làm phương tiện chuyển đổi các số có dấu phẩy động thành các kiểu số nguyên hoặc các kiểu số nguyên lớn hơn thành các số nhỏ hơn không? Theo tôi, việc truyền vai phải phù hợp với các tình huống trong đó một nhà thiết kế ngôn ngữ chỉ có thể chọn một hành vi hợp lý và các phương tiện chuyển đổi khác nên được sử dụng khi các hành vi khác nhau có ý nghĩa trong các bối cảnh khác nhau. Ví dụ, người ta có thể lập luận rằng một ngôn ngữ nên (int)1.5-2*(int)(-1.5)năng suất 3, 4, 5, hoặc 6, nhưng nếu (int)đã được thay thế bằng truncInt, roundPeriodicInt, floorInt, hoặc roundEvenInt, ...
supercat

... Sẽ không có sự mơ hồ. Tương tự như vậy, khi truyền loại số nguyên dài hơn thành loại ngắn hơn, có những trường hợp số không phù hợp với loại nhỏ hơn được dự kiến ​​và sẽ bao bọc, và có những trường hợp số đó bất ngờ và sẽ gây ra ngoại lệ. Các ngôn ngữ khác nhau có hành vi khác nhau với các diễn viên như vậy, do đó, hầu như không tự chứng minh hành vi nào mà một diễn viên nên có. Trừ khi một ngôn ngữ có cả hai kiểu số nguyên bao bọc và không bao bọc (một khái niệm thiết kế tốt, IMHO, mặc dù tôi không biết bất kỳ ngôn ngữ nào), chỉ định liệu việc bao bọc có được mong đợi hay không.
supercat

@supercat: Ít nhất là trong C, một diễn viên luôn chỉ định cùng một loại chuyển đổi sẽ được thực hiện hoàn toàn bằng cách gán cho một đối tượng cùng loại - nếu đó là một trong những chuyển đổi (chủ yếu là các chuyển đổi giữa các loại số học) có thể thực hiện ngầm. Các loại chuyển đổi khác, ví dụ: chỉ định loại làm tròn / cắt ngắn cho dấu phẩy động, có thể được thực hiện thông qua các lệnh gọi hàm.
Keith Thompson

Chắc chắn các chức năng có thể được sử dụng; quan điểm của tôi là tôi nghĩ chức năng hoặc các thành viên nên được coi là những phương tiện thích hợp thực hiện chuyển đổi mà kết quả có thể không đại diện cho các giá trị ban đầu. Tôi biết C cho phép chuyển đổi từ float sang số nguyên ngầm định và khả năng tương thích chỉ ra rằng nó có thể sẽ luôn phải làm như vậy, nhưng điều đó không có nghĩa là nó nên như vậy. Pascal đòi hỏi một cuộc gọi đến Roundhoặc Trunc--IMHO một thiết kế sạch hơn nhiều.
supercat

1

Trong khi truyền, bạn đọc thể hiện của một lớp như thể nó là thể hiện của một lớp khác. Nó có thể được áp dụng cho cặp lớp này hay không. Không có thời gian chạy làm việc ngoại trừ kiểm tra. Thường thì sự không tương thích có thể có thể được bắt gặp trên giai đoạn biên dịch.

Trong khi chuyển đổi, bạn kết hợp lại hoặc kể lại các trường của một thể hiện của một lớp thành một thể hiện của một lớp khác. Nếu có một chức năng cho nó, nó có thể được áp dụng hoặc không cho trường hợp này. Tất cả các công việc được thực hiện trong thời gian chạy. Không có lỗi có thể được kiểm tra trong khi biên dịch.


Nghe có vẻ đặc thù ngôn ngữ. Bạn đang đề cập đến ngôn ngữ nào?
Keith Thompson

Java, C ++, C #, Pascal / Delphi.
Gangnus

C ++ sử dụng thuật ngữ "cast" và "convert" giống như tiêu chuẩn C, với việc bổ sung một số từ khóa cast chuyên dụng; xem câu trả lời của tôi
Keith Thompson
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.