Có phải là thực tế xấu khi đặt tên một biến không sử dụng với một dấu gạch dưới duy nhất?


44

Thông thường khi cú pháp của ngôn ngữ yêu cầu tôi đặt tên cho một biến không bao giờ được sử dụng, tôi sẽ đặt tên cho nó _.

Trong tâm trí của tôi, điều này làm giảm sự lộn xộn và cho phép tôi tập trung vào các biến có ý nghĩa trong mã. Tôi thấy nó không phô trương để nó tạo ra hiệu ứng "ngoài tầm nhìn, mất trí".

Một ví dụ phổ biến về nơi tôi làm điều này là đặt tên các truy vấn con trong SQL.

SELECT *
FROM
(
    SELECT *
    FROM TableA
    JOIN TableB
        ON TableA.ColumnB = TableB.ColumnB
    WHERE [ColumnA] > 10
) _ --This name is required, but never used here
ORDER BY ColumnC

Một ví dụ khác là một biến vòng lặp không được sử dụng.

array = [[] for _ in range(n)] # Defines a list of n empty lists in Python

Tôi sử dụng kỹ thuật này rất ít, chỉ khi tôi cảm thấy rằng một tên mô tả không thêm gì vào mã, và trong một số ý nghĩa sẽ loại bỏ nó bằng cách thêm nhiều tên để nhớ. Trong một số cách, tôi xem nó tương tự như vartừ khóa trong C #, mà tôi cũng sử dụng một cách tiết kiệm.

Đồng nghiệp của tôi không đồng ý. Họ nói rằng thậm chí có một tên nhân vật (chữ cái) là tốt hơn _.

Tôi có lầm không? Là nó thực hành xấu để làm điều này?


4
Tôi nghĩ rằng tên biến nên tuân theo lý thuyết thông tin, tức là độ dài là xác suất đối ứng nhật ký của việc sử dụng chúng (biến chung có tên ngắn). Một chữ cái duy nhất có vẻ như sai cách để đi.
dan_waterworth

2
@dan_waterworth Việc sử dụng các ký tự đơn hoặc kép làm bí danh bảng là một cách thực hành khá phổ biến trong các tập lệnh SQL. Vì bạn thường phải viết rất nhiều mã [table].[column]định danh, nó giúp dễ đọc hơn rất nhiều khi chỉ sử dụng [T].[column]. Nó phụ thuộc vào kịch bản của khóa học. Một chút lựa chọn như thế là hoàn toàn tốt, nhưng nếu một kịch bản rất lớn, tôi có thể sử dụng các tên mô tả nhiều hơn.
CodexArcanum

5
Tôi muốn bạn sử dụng "giả". Điều này hét lên với tôi rằng họ đang ở đó bởi vì ngôn ngữ đòi hỏi một biến không có ngữ cảnh ngữ nghĩa ngoài vài dòng này. _ không đọc tốt cho một con người. (một trong những lý do tôi ghét PERL - Tôi không thể gõ hoặc đọc nó)
Chris Cudmore

1
Lưu ý bên lề: Những gì bạn đặt tên có một bảng dẫn xuất , không phải là truy vấn con.
Nick Chammas

2
Từ khóa var trong c # không có nghĩa này, nó chỉ là một khai báo biến thông thường trong đó loại được suy ra.
Francesco De Vittori

Câu trả lời:


60

Tất cả các tên nên có ý nghĩa. Nếu _là một tiêu chuẩn nổi tiếng tại công ty của bạn hoặc trong cộng đồng rộng lớn hơn, thì nó sẽ có ý nghĩa như một "cái tên không quan trọng". Nếu không, tôi sẽ nói đó là thực tế tồi. Sử dụng tên mô tả cho những gì bạn đề cập đến, đặc biệt là vì tên này có thể quan trọng trong tương lai.


13
+1. dummysẽ tốt, joined_absẽ tốt hơn
Blrfl

5
+1, Có một quy ước nơi tôi làm việc để sử dụng '_' cho các biến không được sử dụng. Tôi nghĩ đó là một quy ước tốt, nhưng tôi đồng ý với câu trả lời này cho trường hợp của OP. Các codebase lý tưởng nên trông như thể chúng được viết bởi một người duy nhất.
dan_waterworth

20
"_" là một tiêu chuẩn nổi tiếng với Python.
Neil G

2
Nếu công ty của bạn sử dụng bất kỳ Perl nào, mặt khác, sử dụng $ _ có thể gây ra hành vi đôi khi đáng ngạc nhiên.
Plutor

2
Trong prolog, dấu gạch dưới chỉ ra rằng biến đó sẽ ẩn danh và không được sử dụng.
Ivan

44

Tôi sẽ nói rằng đó là một thực tế chấp nhận được. Đây là một trường hợp hiếm hoi mà tôi cho rằng đa số là sai và cần cập nhật kiến ​​thức về các ý tưởng lập trình gần đây. Trong nhiều ngôn ngữ, đặc biệt là các ngôn ngữ chức năng dựa trên ML như Haskell và OCaml, việc sử dụng _như một biến "không sử dụng" là cực kỳ phổ biến. Ngay cả Lua, không cung cấp hỗ trợ ngôn ngữ rõ ràng cho nó, khuyến khích sử dụng _như một trình giữ chỗ theo quy ước.

Một số ngôn ngữ (Haskell, Lua và DI nghĩ ra khỏi đỉnh đầu của tôi) cũng đưa ra một quy ước trong đó các biến dẫn đến một dấu gạch dưới không tạo ra các cảnh báo của trình biên dịch về "biến cục bộ không sử dụng" làm cho _tên biến không sử dụng ngắn nhất. Bạn có thể sử dụng một cái gì đó như _unusednhưng tôi đồng ý với bạn rằng nó chỉ làm cho lộn xộn.


Trong trường hợp cụ thể của SQL, tôi đã xem xét nó và đồng nghiệp có thể đúng ở đây. Tôi thường sử dụng một chữ cái viết hoa duy nhất cho các bí danh bảng (và thường là R (esults) cho các mục phụ). Tôi nghĩ rằng việc sử dụng *trong các lựa chọn là một điều rất tồi tệ, bởi vì nếu bảng thay đổi, tập kết quả của bạn cũng thay đổi bất ngờ. Vì vậy, tôi thường sẽ cần bí danh một ký tự để xác định các cột tôi đang chọn. Nếu bạn ngừng sử dụng *, bạn sẽ ngừng cần một tên "không sử dụng".
CodexArcanum

11
Nói đúng ra, ít nhất là trong Haskell, _là một mô hình, không phải là một biến. Đó là một sự khác biệt tinh tế, nhưng điều đó có nghĩa là bạn có thể sử dụng nó nhiều lần trong một cái gì đó như thế (x, _, _) = ..., trong khi cố gắng liên kết cùng một biến nhiều lần sẽ là một lỗi.
hammar

12

Trong Python chắc chắn _được chấp nhận. Tuy nhiên nó có thể xung đột với gettextbí danh _().

Các quy ước phổ biến khác là dummy, unused; một mình hoặc là tiền tố.

Một số công cụ phân tích mã nhận thức được các quy ước này và sẽ không đưa ra các cảnh báo biến không sử dụng:

  • PyLint cho _hoặcdummy
  • PyDev cho bất kỳ biến nào bắt đầu bằng _, unusedhoặcdummy

2
Ngoài ra, sử dụng _cho các biến giả trong python sẽ xung đột với _giá trị trả về cuối cùng. Ví dụ, trong trình thông dịch, nếu bạn thực hiện 5*5trên dòng 1; sau đó trên dòng 2 _sẽ có giá trị 25. Tuy nhiên nếu sau đó bạn đặt x,_ = (3,'not used'), bạn sẽ thấy đó _là bây giờ not usedthay vì giá trị được trả lại cuối cùng cho đến khi bạn del _. Bạn có thể không nên sử dụng _cho giá trị trả lại cuối cùng trong mã thực; nhưng nó thường tiện dụng trong trình thông dịch khi thử những thứ mới.
dr jimbob

4
Vâng, _như giá trị trả lại cuối cùng chỉ hoạt động trong vỏ tương tác.
vartec

Lua cũng vậy. Sử dụng _ là tiêu chuẩn thực hành
sylvanaar

11

Nó phụ thuộc vào hệ sinh thái mà mã này sẽ tồn tại. Nếu _là một tiêu chuẩn được chấp nhận để chỉ ra "biến giả" / "đầu ra không sử dụng", thì bằng mọi cách, hãy gắn bó với nó. Nếu không, hãy tìm hiểu những gì và sử dụng nó.

Một số ngôn ngữ lập trình (ví dụ: Haskell) thậm chí có định danh 'đặc biệt' này được tích hợp vào cú pháp của chúng cho chính xác các mục đích bạn đề cập.


5

Cẩn thận, _ đã có một ý nghĩa nội tại trong một số ngôn ngữ

Trong Python:

9.6. Biến riêng và tài liệu tham khảo lớp-địa phương

nhập mô tả liên kết vào đây Các biến đối tượng của Private Private mà không thể truy cập được ngoại trừ từ bên trong một đối tượng không tồn tại trong Python. Tuy nhiên, có một quy ước được tuân theo bởi hầu hết mã Python: tên có tiền tố gạch dưới (ví dụ _spam) phải được coi là một phần không công khai của API (cho dù đó là hàm, phương thức hay thành viên dữ liệu) . Nó nên được coi là một chi tiết thực hiện và có thể thay đổi mà không cần thông báo trước.

Ngoài ra còn có một đề cập khác trong PEP 8 (Hướng dẫn về Phong cách cho Mã Python):

Mô tả: Kiểu đặt tên

_single_lead_underscore: chỉ số "sử dụng nội bộ" yếu. Ví dụ: từ M nhập * không nhập các đối tượng có tên bắt đầu bằng dấu gạch dưới.

Trong C #:

Nó thường được sử dụng để đánh dấu các biến riêng tư có thuộc tính công khai / nội bộ. Nhưng thực tế thường bị coi thường trong những ngày này .

Trong JavaScript:

Có một thư viện được gọi là underscore.js sử dụng dấu gạch dưới làm tiền tố cho các phần mở rộng nguyên mẫu không chuẩn.

Thí dụ:

var object = { some:'stuff' };
var newObject = _.clone(object);

Dẫn tôi đến quan điểm của tôi. Có gì sai với các quy ước biến giữ chỗ cổ điển.

var i, j, k, l; // iterator placeholders
var x, y, z, xx, yy, zz // value placeholders
var foo, bar, bas, fixx, buzz, qux, etc... // demonstration placeholders

Tại sao sử dụng một quy ước tùy chỉnh mà một số có thể giải thích sai khi có sẵn nhiều quy ước phổ biến?


Trong Scala: đó là biểu tượng ký tự đại diện / giữ chỗ, nhưng là một trình giữ chỗ, bạn chỉ có thể tham chiếu nó một lần .
Rex Kerr

@RexKerr Thú vị. Hãy chỉnh sửa nó thành câu trả lời nếu bạn muốn. Tôi sẽ nhưng tôi không quen với scala.
Evan Plaice

Một bình luận nên làm. Bất cứ ai sử dụng Scala đều biết, và bất kỳ ai không sử dụng Scala có thể sẽ không có khả năng tương thích Scala ở đầu danh sách lý do để / không làm điều gì đó.
Rex Kerr

Tôi nghĩ rằng việc sử dụng một trong những trình giữ chỗ "quy ước" cho các biến không được sử dụng sẽ là một cách làm tồi tệ vì nó sẽ khiến tôi nghĩ rằng, "tại sao anh chàng này lại không đặt tên cho thứ này tốt hơn ??" và sau một thời gian tôi sẽ phát hiện ra nó là do biến không được sử dụng.
igorsantos07

@ igorsantos07 Tôi hoàn toàn đồng ý. Sở thích của tôi sẽ là đưa ra một tên mô tả, ngay cả đối với các biến tạm thời. Điểm của câu trả lời này là để chứng minh tại sao gạch dưới không phải là một lựa chọn tốt cho quy ước đặt tên; do ý nghĩa từ trước trong nhiều ngôn ngữ.
Evan Plaice

2

Tôi sử dụng "hình nộm" cho loại điều đó. Hoặc "tào lao", nếu tôi chỉ đang thử nghiệm một cái gì đó :) Đặt tên cho các biến của bạn để mô tả chúng là gì. Nếu chúng là giả, các biến không được sử dụng, hãy đặt tên cho chúng như vậy.


0

Tôi thấy đó là một thực hành xấu bởi vì

  • bạn không nên có biến vô hình trong mã của bạn. Nếu bạn cảm thấy bạn nên lý do có thể được thảo luận.

  • ngôn ngữ Go sử dụng từ khóa này để chỉ ra rằng không có biến nào là đích của một trong nhiều trả về của hàm. Nếu ngôn ngữ của bạn không có nhiều trả về thì không cần thiết. Quy ước đặt tên của bạn sẽ làm tổn thương bạn vào ngày bạn sẽ sử dụng ngôn ngữ bằng cách sử dụng _ làm ký hiệu ngôn ngữ chuẩn.

(Tôi không biết Python: cấu trúc này có thực sự cần thiết không?)


2
Nếu bạn sử dụng nó để lọc nhiều trả về, thì đó cũng chỉ là sử dụng nó cho các đối số hàm giả. Trên thực tế, không có nhiều khác biệt giữa hai loại: trong các ngôn ngữ chức năng khớp mẫu, bạn có thể viết let (a,b,_) = f(x,y,z)tốt như let f(x,y,_) = (g(x),h(x),g(y))hoặc bất cứ thứ gì. - Và, vâng, thường hữu ích khi có các tham số giả: không phải là định nghĩa duy nhất của hàm, mà đối với hàm đa hình hoặc một với các định nghĩa khớp mẫu thay thế thường là điều tự nhiên phải làm.
leftaroundabout

1
Điểm thứ hai của bạn mâu thuẫn với điểm chính của bạn: trong Go, về cơ bản có nghĩa giống như "Tôi không sử dụng giá trị này".
Casey Kuball

0

Nó có thể hợp lệ về mặt cú pháp và nó có thể là một phần của tiêu chuẩn.

Như đã nói, đó là điều mà tôi sẽ yêu cầu ai đó thay đổi trong đánh giá mã. Tôi cũng sẽ không bao giờ đưa nó vào một tiêu chuẩn mã hóa, và sẽ cố gắng loại bỏ nó khỏi một tiêu chuẩn hiện có. Nó chỉ khó đọc hơn và không siêu ý nghĩa.


0

Tôi nghĩ đó là sai bởi vì:

1) Khó nhìn hơn vì không có nhiều pixel.

2) Nếu có nhiều hơn một _, làm sao bạn biết cái nào? - hoặc rằng một nhà phát triển mới đã 'tuân theo các quy tắc' và giữ cho việc sử dụng của họ cực kỳ cục bộ trong phạm vi?

3) Đó là một thực tế không hữu ích. Sử dụng tên biến một chữ cái là trường học cũ (tức là giáo dục ban đầu của tôi!). Tôi sẽ thấy họ ... và sau đó thấy các bình luận được thêm vào để nói những gì mã làm và đó là một thực tiễn xấu trong thế giới ngày nay. Tôi sử dụng tên biến dài càng nhiều càng tốt để mọi người, bất kể cấp độ lập trình hay làm quen với mã đều có thể "đọc nó" gần giống như tiếng Anh. Sử dụng tên 1 chữ cái là một cách thực hành cực kỳ phổ biến với mã cũ và với các lập trình viên cũ (một lần nữa, bao gồm cả tôi) nhưng điều đó không làm cho nó ổn.


9
"Làm thế nào để bạn biết cái nào" bạn không : đó chính xác là điểm, bạn không sử dụng biến. Vì vậy, nó cũng không thành vấn đề nếu _đã được sử dụng trong phạm vi bên ngoài; rằng người ta sẽ bị che khuất (hoặc bất cứ ngôn ngữ nào của bạn làm trong những trường hợp như vậy), nhưng dù sao thì chúng không được sử dụng.
leftaroundabout

0

Để tránh xung đột không gian tên và cho phép gỡ lỗi, trong trường hợp tên biến đó là đầu mối duy nhất của bạn, tốt hơn nên gọi nó là "gia nhập_ab_unuse".

Lấy cảm hứng từ Birfl.


0

Vâng, đó là một thực tế xấu vì hai lý do:

  1. Tiền tố một biến không được sử dụng với dấu gạch dưới không phải là một tiêu chuẩn được chấp nhận rộng rãi. Nó có thể sẽ bị bỏ qua "không chuyên".
  2. Tôi đã thấy một số người tiền tố biến thành viên riêng tư có dấu gạch dưới và tiêu chuẩn của bạn sẽ gây nhầm lẫn lớn cho những người như vậy.

0

Những gì bạn đang cố gắng làm là viết mã trong một phiên bản SQL đẹp hơn mà không có vấn đề buộc bạn phải phát minh ra một tên cho thứ gì đó vô dụng.

Dấu gạch dưới gần như vô hình, vì vậy có vẻ như bạn đang ở trong ngôn ngữ đó. Nếu chỉ có khoảng trắng có thể được sử dụng như một định danh, nó sẽ hoàn hảo, phải không?

Nhưng bạn không ở một ngôn ngữ khác và những gì bạn đang làm không phải là một cách rõ ràng để thực hiện một phần mở rộng ngôn ngữ.


0

Nó phụ thuộc vào ngôn ngữ. Trong java , vâng, điều này rất tệ và có thể là một xu hướng nguy hiểm khi thêm vào mã của bạn, phần lớn là do các công cụ sử dụng sự phản chiếu không xử lý tốt các dấu gạch dưới, vì chúng nằm ngoài các quy ước đặt tên biến java. Ở python , điều này cũng xấu nhưng không tệ bằng. Trong clojure , nó ổn 100% và trên thực tế, thành ngữ của nó là sử dụng _'s làm chủ sở hữu vị trí trong một tuyên bố let.

Hãy nhớ rằng mỗi ngôn ngữ có toàn bộ cú pháp và tập hợp thành ngữ riêng, vì vậy bạn phải đánh giá tốt / xấu về các thành ngữ này, thay vì theo thuật ngữ tuyệt đối.


5
Tôi không đồng ý rằng đây là thực hành xấu ở trăn. Đó là một quy ước được hiểu rộng rãi
Daenyth

0

Điều này sẽ không tốt trong perl, sử dụng $ _ (và đôi khi _) làm biến đặc biệt.

Nói chung, tôi tránh xa nó chỉ vì _ dường như là một ngôn ngữ cụ thể. Nếu tôi thấy mã của bạn, tôi sẽ ở trong tài liệu tìm kiếm _ là gì, cho đến khi tôi nhận ra đó chỉ là một hình nộm. Không có gì sai với DUMMY, $ DUMMY, sao cũng được.


0

Tôi sẽ tránh dấu gạch dưới ở đầu vars trừ khi bạn chắc chắn rằng họ không có xu hướng chỉ ra một thứ khác trong một ngôn ngữ hoặc khuôn khổ nhất định được sử dụng nhiều. Chẳng hạn, trong Python, dấu gạch dưới kép có xu hướng chỉ ra một var ma thuật. Trong JQuery và các thư viện JS khác, một dấu gạch dưới đơn có xu hướng chỉ ra một var dự phòng cho các ghi đè không gian tên. Đây cũng là một quy ước đặt tên phổ biến cho các tệp bao gồm các tệp có xu hướng chuyển sang mã xử lý bao gồm ở dạng var.

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.