Thuật ngữ được sử dụng để mô tả một chức năng / phương thức sửa đổi đối tượng mà nó được gọi là gì?


12

Xin lỗi cho câu hỏi chung chung. Tôi đã tìm kiếm khắp nơi và tìm thấy rất nhiều chủ đề tương tự như thế này, tuy nhiên không phải là một câu trả lời cho câu hỏi cụ thể của tôi - có lẽ vì thuật ngữ tôi đang tìm kiếm thậm chí không tồn tại.

Một người bạn của tôi đang học lập trình, cụ thể là JavaScript và anh ấy hỏi tôi tại sao điều này không hiệu quả:

var a = "Hello World";
a.replace("Hello", "Goodbye");

console.log(a)  // Logs "Hello World"

Lý do là vì replacekhông sửa đổi a, vì các chuỗi là bất biến trong JavaSript. Vì nó trả về một chuỗi, bạn cần phải làm một cái gì đó như ...

var a = "Hello World";
a = a.replace("Hello", "Goodbye");

console.log(a);  // Logs "Goodbye World"

Tuy nhiên, giải pháp thay thế là một chức năng như JavaScript reverse(), vì nó sửa đổi bất cứ điều gì gọi nó. Ví dụ:

var fruits = ["Apples", "Oranges", "Bananas"];
fruits.reverse();

console.log(fruits)  // ["Bananas", "Oranges", "Apples"]

Khi bạn tôi hỏi tôi tại sao anh replaceta không làm việc, tôi nhận ra tôi đang tìm một từ mà tôi không biết (theo như tôi biết) ...

"Bạn phải đặt chuỗi thành" chuỗi thay thế chuỗi ", bởi vì chức năng thay thế là ____."

Bạn không cần đặt một mảng bằng "mảng chấm ngược", vì đảo ngược là ____. "

Tôi quen thuộc với các chức năng nguyên mẫu mặc dù tôi không tin đó là từ mà tôi đang tìm kiếm. Bất cứ ai có thể giúp tôi điền vào những khoảng trống?


6
Có lẽ từ này là "mutator"? như trong : You don't need to set an array equal to "array dot reverse", because reverse is a mutator function. Tôi nghĩ rằng tôi đã nghe thuật ngữ đó để chỉ các chức năng "biến đổi" thể hiện gọi chúng. Nhưng có lẽ bạn nên kiểm tra lại ở một nơi khác.
Thất

Cảm kích điều đó! Tôi mới đọc một số về Phương pháp Mutator và tôi nghĩ rằng nó chắc chắn phù hợp với cuộc trò chuyện này khá tốt. Chắc chắn trong lĩnh vực của những gì tôi đang tìm kiếm.
Santi

Tôi bối rối: trong tiêu đề, bạn hỏi về một chức năng mà sửa đổi các đối tượng đó gọi nó, nhưng trong ví dụ của bạn, bạn thấy phương pháp cải tiến đối tượng chúng được gọi vào , tức là hoàn toàn ngược lại của tiêu đề. Đó là cái nào trong hai?
Jörg W Găngag

Vâng chắc chắn một trong những giải thích trong 30 dòng chi tiết. Tôi sẽ sửa đổi tiêu đề cho chính xác, cảm ơn vì đã đề phòng!
Santi

Câu trả lời:


12

Cặp khái niệm mà bạn đang tìm kiếm là các tham số có thể thay đổi / không thay đổi và tại chỗ / trả về kết quả.

Trong ví dụ của bạn:

Bạn phải đặt chuỗi thành "chuỗi thay thế chuỗi", bởi vì hàm thay thế hoạt động trên một chuỗi, trong python, là bất biến nên hàm thay thế trả về một chuỗi mới.

Đối với một lập trình viên C / C ++, điều này quen thuộc hơn là các tham số "được truyền bởi giá trị", thay vì "được truyền bởi tham chiếu", điều này làm cho chúng không thay đổi và trả về kết quả.

Bạn không cần đặt một mảng bằng "mảng đảo ngược", bởi vì đảo ngược hoạt động trên một mảng, có thể thay đổi , do đó có thể thực hiện thay đổi tại chỗ trước khi quay lại.

Trong các ngôn ngữ như C / C ++, điều này được gọi là tham số "được truyền bởi tham chiếu" tức là truyền địa chỉ mà nếu không được sửa đổi bởi const, cho phép hàm thay đổi, thay đổi , nội dung của địa chỉ đó thay đổi kết quả tại chỗ trước khi trả về.

Tất nhiên, không có gì bất thường khi có một hàm trả về kết quả của cả hai cơ chế, ví dụ: int SomeFn(int p1, int p2, int *ErrCode) , có thể, có khả năng trả về kết quả cả về giá trị trả về và bằng cách sửa đổi nội dung của ErrCode.

Phương pháp thứ 3

Để hoàn thiện, cơ chế thứ 3 để trả về kết quả là theo hiệu ứng phụ hoặc từ khóa toàn cầu , tức là sửa đổi phạm vi tệp, toàn bộ chương trình, chia sẻ hoặc giá trị môi trường. Điều này thường được coi là tin xấu vì, trừ khi có tài liệu rất tốt, bạn chỉ có thể tìm hiểu những gì đang được thay đổi bằng cách đọc mã cẩn thận. Trong các ngôn ngữ như C / C ++, điều này quá dễ thực hiện bằng cách có một biến phạm vi bên ngoài với một tên cụ thể , thậm chí có thể trong một mô-đun khác và không che giấu biến phạm vi cục bộ cùng tên. Trong Python, trong khi bạn có thể đọc các giá trị của các giá trị trong phạm vi bên ngoài, trừ khi các giá trị phạm vi bên ngoài được đặt rõ ràng là có sẵn để được sửa đổi với , cố gắng sửa đổi một biến phạm vi bên ngoài sẽ tự động tạo ra một cục bộ cùng tên.global


À, tôi quen thuộc với các thuật ngữ này, mặc dù tôi không chắc có từ nào thực sự mô tả chính hàm đó không . Như trong, (The reverse function is a _______ function.) Điều đó đã được nói, đây gần như là một câu trả lời giống hệt với câu trả lời mà tôi đã kết bạn, vì vậy tôi đánh giá cao sự xác nhận của bạn - mặc dù tôi vẫn tự hỏi liệu có điều khoản cụ thể nào không. Tôi sẽ để câu hỏi mở một chút nhưng chắc chắn sẽ chấp nhận đây là câu trả lời trong trường hợp những từ này không tồn tại.
Santi

2
Trong một số ngôn ngữ, chẳng hạn như python, bạn cũng có thể có các lớp tự sửa đổi - trong khi trong một số bối cảnh, "vá khỉ" được coi là một điều tốt trong nhiều ngôn ngữ, nó được coi là "mã tự sửa đổi" và bị cấm. Bạn cũng có thể có "mã tiến hóa" trong đó các đoạn mã được "đột biến" và / hoặc kết hợp sau đó được kiểm tra và chọn cho hiệu suất "tốt nhất" theo một cách nào đó.
Steve Barnes

-1. Cho dù các chuỗi là có thể thay đổi hoặc bất biến không liên quan đến chức năng đang hoạt động trên nó. Hàm này không thể thay đổi hoặc không thay đổi và không phải là "trở lại hoặc tại chỗ". Các hàm có thể sửa đổi các đối số của chúng và vẫn trả về.
Miles Rout

@MilesRout đã thêm rằng các hàm sửa đổi tại chỗ vẫn trả về và một số ví dụ C / C ++ cho sự rõ ràng cộng với kết quả bằng các tác dụng phụ cho sự hoàn chỉnh.
Steve Barnes

4

Cách ưa thích của tôi để thể hiện nó là:

  • reversePhương thức Array đang biến đổi . Đó là một kẻ gây đột biến . Một trường hợp đặc biệt phổ biến là setter .

  • replacePhương thức String không biến đổi . Nó không phải là một kẻ gây đột biến . Nếu nó không sửa đổi bất cứ điều gì , nó không có tác dụng phụ . Một trường hợp đặc biệt phổ biến là một getter .

  • Vì Chuỗi JavaScript là bất biến , nên các phương thức Chuỗi không thể bị đột biến.

    "Xin chào thế giới" .replace ("Xin chào", "Tạm biệt");

    nên làm bạn khó chịu. Nó không sửa đổi một chuỗi ký tự. Nó loại bỏ kết quả. Máy phân tích mã tĩnh đôi khi có thể phát hiện các lỗi như vậy.

  • Vì Mảng JavaScript có thể thay đổi , nên các phương thức Array có thể bị đột biến. JavaScript có xu hướng sử dụng Mảng như các thùng lưu trữ cục bộ, dễ dàng sửa đổi và sao chép không thường xuyên.

2

Đôi khi, khi được sử dụng trong ngữ cảnh của lập trình chức năng thuần túy, tôi đã nghe thấy các hàm sửa đổi giá trị đầu vào (và do đó không phải là các hàm thuần túy) được gọi là phá hoại . Tôi không chắc chắn nếu đây là thuật ngữ chính xác.

Trong trường hợp của bạn, bạn sẽ nói:

Bạn phải đặt chuỗi thành "chuỗi thay thế chuỗi", vì chức năng thay thế không mang tính hủy diệt .

Bạn không cần thiết lập một mảng bằng "mảng chấm ngược", vì ngược lại là phá hoại .


1

Có lẽ là tinh khiết là từ bạn đang tìm kiếm?

replace()là (hoặc dường như) thuần túy bởi vì nó không giống như nó có bất kỳ tác dụng phụ nào (nghĩa là sửa đổi chuỗi) trong khi reverse()không tinh khiết vì nó thay đổi trạng thái của mảng.


Đó là một khái niệm liên quan, nhưng cũng bao hàm các thuộc tính khác (ví dụ: không truy cập trạng thái toàn cầu và luôn mang lại cùng một đầu ra cho cùng một đầu vào).
Jacob Raihle

1

Chúng thường được phân tách thành các hàm và phương thức (trong đó các phương thức là tập hợp con của các hàm). Hàm là một phần của mã có thể được gọi một cách cô lập, trong khi đó một phương thức có khái niệm về 'bối cảnh' hiện tại mà nó hoạt động. Hành động của một phương thức thay đổi trạng thái bối cảnh của nó.

Trong lập trình hướng đối tượng, bối cảnh là ví dụ mà hàm đang hoạt động.


0

Tôi không biết rằng có một câu trả lời chính thức, nhưng đây là hai bạn có thể thích.

Thủ tục

Chỉ bởi vì nó có vẻ như là một câu trả lời tốt cho câu hỏi này , trông rất giống câu hỏi của bạn BTW-- bạn nên kiểm tra nó.

Hoạt động đơn phương tại chỗ

Xem lại trang này: java.util.feft . Nó cung cấp một loại tên tạo cho các đại biểu (chữ ký đầu vào / đầu ra) của các nguyên mẫu khác nhau, ví dụ: một đại biểu lấy một đối số và trả về không có gì được gọi là người tiêu dùng .

Bây giờ, là một sinh viên sắc sảo của OOP, bạn nên biết rằng một phương thức chỉ là một hàm có một tham số ẩn (this ). Vì nó được cung cấp dưới dạng tham chiếu, nên nó đóng vai trò là tham số đầu vào và đầu ra.

Theo những người Java này (và họ có vẻ khá thông minh), một đại biểu chấp nhận một đầu vào duy nhất và trả về một giá trị cùng loại được gọi là toán tử đơn nguyên .

Bây giờ trong trường hợp array::Reverse(), một mảng không phải là bất biến và có khả năng chiếm nhiều không gian, vì vậy sẽ hiệu quả và thuận tiện hơn khi thực hiện thao tác tại chỗ. Do đó Reverse()là một nhà điều hành unary tại chỗ .

Nhưng với tôi, "toán tử" là một ký hiệu đặc biệt (như toán tử cộng, còn được gọi là +) hoặc một từ khóa toán học như thế nào mod. Do đó, tôi thích gọi nó là ion operat , mang lại hoạt động đơn phương tại chỗ .


Bạn đang trộn lẫn các khái niệm. Reverse()không phải là một nhà điều hành, một nhà điều hành unary không cần trả về một giá trị cùng loại (ví dụ !, delete, typeof), và các nhà khai thác không phải là đại biểu. Nhưng "tại chỗ" là một thuật ngữ tốt cho một phương thức sửa đổi thể hiện của nó. [Tôi đã không bỏ phiếu, nhưng có vẻ như ai đó đã bỏ phiếu tất cả các câu trả lời mặc dù chúng đều hữu ích.]
Jerry101

Không chắc chắn bạn đang theo dõi. Bất kỳ nguyên mẫu có thể được đại diện bởi một đại biểu. "Toán tử" không hoạt động đối với tôi (như tôi đã nói) vì vậy tôi nói "Vận hành", và thực sự Reverse()là một hoạt động đơn phương. Nhưng nhìn chung, tôi đồng ý rằng điều này hơi kỳ quặc, nhưng tôi đang sử dụng nguyên văn thuật ngữ từ tài liệu được liên kết , dường như đã được một số người khá thông minh sáng tác. Ít nhất là tốt hơn không có gì.
John Wu

Ồ, tôi hiểu rồi! Lưu ý rằng để trang bị thêm lambdas vào Java, họ đã xây dựng ý tưởng về giao diện chức năng (giao diện Java chỉ có 1 phương thức) để chúng ta có thể chuyển qua các đối tượng Java thông thường để áp dụng làm "hàm". (Brian Goetz có một cuộc nói chuyện công nghệ về việc thêm lambdas. Nhiều lần ông nói rằng "cách tiếp cận rõ ràng sẽ bị hút.") Khi tạo giao diện chức năng cho các đối tượng xử lý luồng, chúng loại các thuật ngữ bị lạm dụng như "toán tử". Thật khó hiểu! Họ đã hết tên tốt. Tôi không nghĩ rằng đó là một nguồn thuật ngữ tốt cho các phương thức OOP không / không sửa đổi đối tượng người nhận.
Jerry101
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.