Hướng dẫn nhanh chóng và kỹ lưỡng về ‘null’: nó là gì và bạn nên sử dụng nó như thế nào – null lúc null là gì

của Christian Neumanns Hướng dẫn nhanh chóng và kỹ lưỡng về ‘null’: nó là gì và bạn nên sử dụng nó như thế nào Ý nghĩa của null là gì? Null được thực hiện như thế nào? Khi nào bạn nên sử dụng null trong mã nguồn của mình và khi nào bạn không nên sử dụng nó? Giới thiệu null là một

Bạn đang xem: null là gì ở null

bởi Christian Neumanns

Hướng dẫn nhanh chóng và kỹ lưỡng về ‘ null ‘: nó là gì và bạn như thế nào nên sử dụng nó

Ý nghĩa của null là gì? null được triển khai như thế nào? Khi nào bạn nên sử dụng null trong mã nguồn của mình và khi nào bạn không nên sử dụng nó?

Giới thiệu

null < / code> là một khái niệm cơ bản trong nhiều ngôn ngữ lập trình. Nó có mặt ở khắp mọi nơi trong tất cả các loại mã nguồn được viết bằng các ngôn ngữ này. Vì vậy, điều cần thiết là phải nắm bắt đầy đủ ý tưởng của null . Chúng ta phải hiểu ngữ nghĩa và cách triển khai của nó, đồng thời chúng ta cần biết cách sử dụng null trong mã nguồn của mình.

Các bình luận trên diễn đàn lập trình viên đôi khi cho thấy một chút nhầm lẫn với null . Một số lập trình viên thậm chí cố gắng tránh hoàn toàn null . Bởi vì họ nghĩ đó là 'sai lầm hàng triệu đô la', một thuật ngữ được đặt ra bởi Tony Hoare, người phát minh ra null .

Đây là một ví dụ đơn giản: Giả sử rằng < code> email_address trỏ đến null . Điều đó có nghĩa là gì? Có nghĩa là Alice không có địa chỉ email? Hay địa chỉ email của cô ấy không rõ? Hay đó là bí mật? Hay nó chỉ đơn giản có nghĩa là email_address là ‘chưa được xác định’ hoặc ‘chưa được khởi tạo’? Hãy xem nào. Sau khi đọc bài viết này, mọi người sẽ có thể trả lời những câu hỏi như vậy mà không do dự.

Lưu ý: Bài viết này là ngôn ngữ lập trình trung lập – càng nhiều càng tốt. Giải thích là chung chung và không ràng buộc với một ngôn ngữ cụ thể. Vui lòng tham khảo hướng dẫn sử dụng ngôn ngữ lập trình của bạn để được tư vấn cụ thể về null . Tuy nhiên, bài viết này chứa một số ví dụ mã nguồn đơn giản được hiển thị trong Java. Nhưng không khó để dịch chúng sang ngôn ngữ yêu thích của bạn.

Run-time implement

Trước khi thảo luận về ý nghĩa của null , chúng tôi cần hiểu cách triển khai null trong bộ nhớ tại thời điểm chạy.

Lưu ý: Chúng tôi sẽ xem xét cách triển khai điển hình trong tổng số null . Việc triển khai thực tế trong một môi trường nhất định phụ thuộc vào ngôn ngữ lập trình và môi trường đích và có thể khác với cách triển khai được hiển thị ở đây.

Giả sử chúng ta có lệnh mã nguồn sau:

  String name = "Bob";  

Ở đây chúng tôi khai báo một biến kiểu String và với số nhận dạng name trỏ đến string "Bob" .

Nói “trỏ tới” là quan trọng trong ngữ cảnh này, bởi vì chúng tôi đang giả định rằng chúng tôi làm việc với loại tham chiếu (và không với loại giá trị ). Tìm hiểu thêm về vấn đề này sau.

Để mọi thứ đơn giản, chúng tôi sẽ đưa ra các giả định sau:

  • Lệnh trên được thực thi trên CPU 16 bit với 16 bit không gian địa chỉ.
  • Các chuỗi được mã hóa dưới dạng UTF-16. Chúng được kết thúc bằng 0 (như trong C hoặc C ++).

Hình dưới đây cho thấy một đoạn trích của bộ nhớ sau khi thực hiện lệnh trên:

Hình 1: Biến name trỏ tới "Bob"

Địa chỉ bộ nhớ trong hình trên được chọn tùy ý và không liên quan đến cuộc thảo luận của chúng ta.

Như chúng ta có thể thấy, string "Bob" được lưu tại địa chỉ B000 và chiếm 4 ô nhớ.

name biến được đặt tại địa chỉ A0A1. Nội dung của A0A1 là B000, là vị trí bộ nhớ bắt đầu của chuỗi "Bob" . Đó là lý do tại sao chúng ta nói: Biến name trỏ đến "Bob" .

Cho đến nay rất tốt.

Bây giờ, giả sử rằng , sau khi thực hiện hướng dẫn trên, bạn thực hiện như sau:

  name = null;  

Bây giờ name trỏ tới null .

Và đây là trạng thái mới trong bộ nhớ:

Hình 2: Biến name trỏ tới null

Chúng tôi có thể thấy rằng không có gì thay đổi đối với chuỗi "Bob" vẫn được lưu trong bộ nhớ.

Lưu ý: Bộ nhớ cần thiết để lưu trữ chuỗi "Bob" sau đó có thể được phát hành nếu có bộ thu gom rác và không có tham chiếu nào khác trỏ đến "Bob" , nhưng điều này không liên quan trong cuộc thảo luận của chúng tôi.

Điều quan trọng là nội dung của A0A1 (đại diện cho giá trị của tên biến) bây giờ là 0000. Vì vậy, biến name không trỏ đến "Bob" nữa. Giá trị 0 (tất cả các bit bằng 0) là giá trị điển hình được sử dụng trong bộ nhớ để biểu thị null . Có nghĩa là không có giá trị nào được liên kết với name . Bạn cũng có thể coi đây là trường hợp không có dữ liệu hoặc đơn giản là không có dữ liệu.

Lưu ý: Giá trị bộ nhớ thực được sử dụng để biểu thị null là giá trị triển khai cụ thể. Ví dụ: Đặc điểm kỹ thuật máy ảo Java nêu ở cuối phần 2.4. “Các loại và giá trị tham chiếu:”

Đặc tả Máy ảo Java không bắt buộc mã hóa giá trị cụ thể null .

Hãy nhớ:

Nếu tham chiếu trỏ đến null , điều đó đơn giản có nghĩa là không có giá trị nào được liên kết với nó.

Về mặt kỹ thuật, , vị trí bộ nhớ được gán cho tham chiếu chứa giá trị 0 (tất cả các bit bằng 0) hoặc bất kỳ giá trị nào khác biểu thị null trong môi trường nhất định.

Hiệu suất

Như chúng ta đã học trong phần trước, các thao tác liên quan đến null cực kỳ nhanh và dễ thực hiện tại thời điểm chạy.

Chỉ có hai loại hoạt động:

  • Khởi tạo hoặc đặt một tham chiếu đến null (ví dụ: name = null ): Điều duy nhất cần làm là thay đổi nội dung của một ô nhớ (ví dụ: đặt thành 0).
  • Kiểm tra xem tham chiếu có trỏ đến null hay không (ví dụ: if name == null ) : Điều duy nhất cần làm là kiểm tra xem ô nhớ của tham chiếu có giữ giá trị 0.

Hãy nhớ:

> Thao tác trên null cực kỳ nhanh và rẻ.

Kiểu tham chiếu so với Giá trị

Cho đến nay, chúng tôi giả định đang làm việc với loại tham chiếu . Lý do cho điều này rất đơn giản: null không tồn tại cho loại giá trị .

Tại sao?

Như chúng ta đã thấy trước đây, một tham chiếu là một con trỏ đến một địa chỉ bộ nhớ lưu trữ một giá trị (ví dụ: một chuỗi, một ngày tháng, một khách hàng, bất kỳ thứ gì). Nếu một tham chiếu trỏ đến null , thì không có giá trị nào được liên kết với nó.

Mặt khác, theo định nghĩa, một giá trị là chính giá trị đó. Không có con trỏ liên quan. Một kiểu giá trị được lưu trữ dưới dạng giá trị của chính nó. Do đó, khái niệm null không tồn tại cho các loại giá trị.

Hình ảnh sau đây thể hiện sự khác biệt. Ở phía bên trái, bạn có thể thấy lại bộ nhớ trong trường hợp biến name là một tham chiếu trỏ đến "Bob". Phía bên phải hiển thị bộ nhớ trong trường hợp biến name là một loại giá trị.

Như chúng ta có thể thấy, trong trường hợp là một loại giá trị, bản thân giá trị được lưu trữ trực tiếp tại địa chỉ A0A1 được liên kết với biến name .

Sẽ còn nhiều điều để nói về kiểu tham chiếu so với giá trị, nhưng điều này nằm ngoài phạm vi của bài viết này. Cũng xin lưu ý rằng một số ngôn ngữ lập trình chỉ hỗ trợ các kiểu tham chiếu, những ngôn ngữ khác chỉ hỗ trợ các kiểu giá trị và một số (ví dụ: C # và Java) hỗ trợ cả hai.

Hãy nhớ:

Khái niệm null chỉ tồn tại cho các loại tham chiếu . Nó không tồn tại cho loại giá trị .

Ý nghĩa

Giả sử chúng ta có một loại người với một trường emailAddress . Cũng giả sử rằng, đối với một người nhất định mà chúng ta sẽ gọi là Alice, emailAddress trỏ đến null .

Điều này có nghĩa là gì? Có nghĩa là Alice không có địa chỉ email? Không nhất thiết.

Như chúng ta đã thấy, điều chúng ta có thể khẳng định là không có giá trị nào được liên kết với emailAddress.

Nhưng tại sao lại không có giá trị nào? Lý do emailAddress trỏ đến null là gì? Nếu chúng ta không biết bối cảnh và lịch sử, thì chúng ta chỉ có thể suy đoán. Lý do cho null có thể là:

Alice không có địa chỉ email. Hoặc…

Alice có một địa chỉ email, nhưng:

  • nó chưa được nhập vào cơ sở dữ liệu
  • nó là bí mật (chưa được tiết lộ để bảo mật lý do)
  • có một lỗi trong quy trình tạo đối tượng người mà không đặt trường emailAddress
  • , v.v. >

    Trong thực tế, chúng ta thường biết ứng dụng và ngữ cảnh. Chúng tôi liên kết trực quan một ý nghĩa chính xác với null . Trong một thế giới đơn giản và hoàn mỹ, null chỉ đơn giản có nghĩa là Alice thực sự không có địa chỉ email.

    Khi chúng tôi viết mã, lý do tại sao một tham chiếu trỏ đến null thường không liên quan. Chúng tôi chỉ kiểm tra null và thực hiện các hành động thích hợp. Ví dụ, giả sử rằng chúng ta phải viết một vòng lặp gửi email cho một danh sách người. Mã (bằng Java) có thể trông như thế này:

     for (Person person: people) {if (person.getEmailAddress ()! = null) {// mã để gửi email} else {logger.warning ("Không có địa chỉ email cho" + person.getName ()); }}  

    Trong vòng lặp trên, chúng tôi không quan tâm đến lý do của null . Chúng tôi chỉ xác nhận thực tế là không có địa chỉ email, ghi lại cảnh báo và tiếp tục.

    Hãy nhớ:

    Nếu tham chiếu trỏ đến null thì điều đó luôn có nghĩa là không có giá trị nào được liên kết với nó.

    Trong hầu hết các trường hợp, null có một giá trị khác ý nghĩa cụ thể phụ thuộc vào ngữ cảnh .

    Tại sao lại là null ?

    Đôi khi điều quan trọng là phải biết lý do tại sao tham chiếu trỏ đến null .

    Hãy xem xét chữ ký chức năng sau trong ứng dụng y tế:

      Danh sách & lt; Dị ứng & gt; getAllergiesOfPatology (Chuỗi bệnh nhân)  

    Trong trường hợp này, trả về null (hoặc danh sách trống) là không rõ ràng. Có nghĩa là bệnh nhân không bị dị ứng, hay có nghĩa là chưa thực hiện xét nghiệm dị ứng? Đây là hai trường hợp rất khác nhau về mặt ngữ nghĩa nên phải xử lý theo cách khác nhau. Nếu không, kết quả có thể đe dọa tính mạng.

    Chỉ cần giả sử rằng bệnh nhân bị dị ứng, nhưng xét nghiệm dị ứng vẫn chưa được thực hiện và phần mềm thông báo với bác sĩ rằng 'không có dị ứng'. Do đó chúng tôi cần thêm thông tin. Chúng ta cần biết lý do tại sao hàm trả về null .

    Thật hấp dẫn khi nói: Chà, để phân biệt, chúng ta trả về null nếu kiểm tra dị ứng vẫn chưa được thực hiện và chúng tôi trả về một danh sách trống nếu không có dị ứng.

    ĐỪNG LÀM ĐIỀU NÀY!

    Đây là thiết kế dữ liệu không hợp lệ vì nhiều lý do.

    Các ngữ nghĩa khác nhau để trả về null so với trả về danh sách trống sẽ cần được ghi chép đầy đủ. Và như chúng ta đều biết, các nhận xét có thể sai (tức là không phù hợp với mã), lỗi thời hoặc thậm chí không thể truy cập được.

    Không có biện pháp bảo vệ nào đối với việc sử dụng sai trong mã ứng dụng gọi hàm. Ví dụ, mã sau đây là sai, nhưng nó biên dịch không có lỗi. Hơn nữa, rất khó phát hiện ra lỗi đối với người đọc. Chúng tôi không thể thấy lỗi khi chỉ nhìn vào mã mà không xem xét nhận xét của getAllergiesOfPatology:

      Danh sách & lt; Dị ứng & gt; dị ứng = getAllergiesOfPatology ("123"); if (dị ứng == null) {System.out.println ("Không dị ứng"); // & lt; - SAI!} else if (Dị ứng.isEmpty ()) {System.out.println ("Kiểm tra chưa xong"); // & lt; - WRONG!} else {System.out.println ("Có dị ứng");}  

    Mã sau cũng sẽ sai:

      Danh sách & lt; Dị ứng & gt; dị ứng = getAllergiesOfP Căn cứ ("123"); if (Dị ứng == null || Dị ứng.isEmpty ()) {System.out.println ("Không có dị ứng"); // & lt; - WRONG!} else {System.out.println ("Có dị ứng");}  

    Nếu null / blank-logic của getAllergiesOfPatology thay đổi trong tương lai, khi đó nhận xét cần được cập nhật, cũng như tất cả mã khách hàng. Và không có biện pháp bảo vệ nào chống lại việc quên bất kỳ thay đổi nào trong số những thay đổi này.

    Nếu sau này, có một trường hợp khác cần được phân biệt (ví dụ: xét nghiệm dị ứng đang chờ xử lý - chưa có kết quả), hoặc nếu chúng tôi muốn thêm dữ liệu cụ thể cho từng trường hợp, sau đó chúng tôi gặp khó khăn.

    Vì vậy, hàm cần trả về nhiều thông tin hơn là chỉ một danh sách.

    Có nhiều cách khác nhau để thực hiện việc này, tùy thuộc vào ngôn ngữ lập trình mà chúng ta sử dụng. Hãy xem một giải pháp khả thi trong Java.

    Để phân biệt các trường hợp, chúng tôi xác định kiểu mẹ AllergyTestResult , cũng như ba kiểu con đại diện cho ba trường hợp ( NotDone , Pending Done ):

      interface AllergyTestResult {}  < / pre> 
      giao diện NotDoneAllergyTestResult mở rộng giao diện AllergyTestResult {}  
      PendingAllergyTestResult mở rộng AllergyTestResult {public Date getDateStarted ();}  

    < pre> giao diện DoneAllergyTestResult mở rộng AllergyTestResult {public Date getDateDone (); Danh sách công khai & lt; Dị ứng & gt; getAllergies (); // rỗng nếu không có dị ứng // không trống nếu có // dị ứng}

    Như chúng ta thấy, đối với mỗi trường hợp, chúng ta có thể có dữ liệu cụ thể được liên kết với nó.

    Thay vì chỉ trả về một danh sách, getAllergiesOfPatology giờ đây trả về một đối tượng AllergyTestResult :

      AllergyTestResult getAllergiesOfPatology (String BNId)  < trước> if (Dị ứngTestResult instanceof NotDoneAllergyTestResult) {System.out.println ("Thử nghiệm chưa được thực hiện"); } else if (Dị ứngTestResult instanceof PendingAllergyTestResult) {System.out.println ("Đang chờ kiểm tra"); } else if (Dị ứngTestResult instanceof DoneAllergyTestResult) {Danh sách & lt; Dị ứng & gt; list = ((DoneAllergyTestResult) Dị ứngTestResult) .getAllergies (); if (list == null) {System.out.println ("Không có dị ứng"); } else if (list.isEmpty ()) {khẳng định sai; } else {System.out.println ("Có dị ứng"); }} else {khẳng định sai;}  

    Lưu ý: Nếu bạn cho rằng đoạn mã trên khá dài dòng và hơi khó viết, thì bạn không đơn độc. Một số ngôn ngữ hiện đại cho phép chúng ta viết mã tương tự về mặt khái niệm ngắn gọn hơn nhiều. Và các ngôn ngữ an toàn bằng null phân biệt giữa các giá trị có thể không và không có giá trị không thể null theo cách đáng tin cậy tại thời điểm biên dịch - không cần phải nhận xét về khả năng vô hiệu của một tham chiếu hoặc để kiểm tra xem một tham chiếu được khai báo là không có giá trị vô tình đã được đặt thành null .

    Hãy nhớ:

    Nếu chúng ta cần biết tại sao không có giá trị nào được liên kết với một tham chiếu, thì dữ liệu bổ sung phải được cung cấp để phân biệt các trường hợp có thể xảy ra .

    Khởi tạo

    Hãy xem xét các hướng dẫn sau:

      String s1 = "foo"; String s2 = null; String s3;  

    Lệnh đầu tiên khai báo biến String s1 và gán cho nó giá trị "foo" .

    Lệnh thứ hai gán null cho s2 .

    Hướng dẫn thú vị hơn là hướng dẫn cuối cùng. Không có giá trị nào được gán rõ ràng cho s3 . Do đó, hợp lý để hỏi: Trạng thái của s3 sau khi khai báo là gì? Điều gì sẽ xảy ra nếu chúng ta ghi s3 vào thiết bị đầu ra của hệ điều hành?

    Hóa ra trạng thái của một biến (hoặc trường lớp) được khai báo mà không gán giá trị phụ thuộc vào chương trình ngôn ngữ. Hơn nữa, mỗi ngôn ngữ lập trình có thể có các quy tắc cụ thể cho các trường hợp khác nhau. Ví dụ: các quy tắc khác nhau áp dụng cho các kiểu tham chiếu và kiểu giá trị, các thành viên tĩnh và không tĩnh của một lớp, các biến cục bộ và toàn cục, v.v.

    Theo tôi biết, các quy tắc sau là điển hình các biến thể gặp phải:

    • Khai báo một biến mà không chỉ định một giá trị là bất hợp pháp
    • Có một giá trị tùy ý được lưu trữ trong s3 , tùy thuộc vào nội dung bộ nhớ tại thời điểm thực thi - không có giá trị mặc định
    • Giá trị mặc định được tự động gán cho s3. Trong trường hợp một loại tham chiếu, giá trị mặc định là null. Trong trường hợp một loại giá trị, giá trị mặc định phụ thuộc vào loại của biến. Ví dụ: 0 cho số nguyên, false cho boolean, v.v.
    • trạng thái của s3 là ' undefined '
    • trạng thái của s3 là' chưa được khởi tạo 'và mọi nỗ lực sử dụng s3 đều dẫn đến lỗi thời gian biên dịch.

    Tùy chọn tốt nhất là tùy chọn cuối cùng. Tất cả các tùy chọn khác đều dễ xảy ra lỗi và / hoặc không thực tế - vì lý do mà chúng tôi sẽ không thảo luận ở đây, vì bài viết này tập trung vào null .

    Ví dụ: Java áp dụng tùy chọn cuối cùng cho các biến cục bộ. Do đó, đoạn mã sau dẫn đến lỗi thời gian biên dịch ở dòng thứ hai:

      String s3; System.out.println (s3);  

    Đầu ra của trình biên dịch:

      error: biến s3 có thể chưa được khởi tạo  

    Hãy nhớ:

    Nếu một biến được khai báo, nhưng không có giá trị rõ ràng nào được gán cho nó, khi đó trạng thái của nó phụ thuộc vào một số yếu tố khác nhau trong các ngôn ngữ lập trình khác nhau.

    Trong một số ngôn ngữ, null là giá trị mặc định cho các loại tham chiếu.

    Khi nào thì sử dụng null (Và khi nào không sử dụng)

    Quy tắc cơ bản rất đơn giản: null chỉ nên được phép khi tham chiếu đối tượng có 'no giá trị liên kết với nó '. (Lưu ý: tham chiếu đối tượng có thể là biến, hằng, thuộc tính (trường lớp), đối số đầu vào / đầu ra, v.v.)

    Ví dụ: giả sử nhập person với các trường name dateOfFirstMarriage :

      interface Person {public String getName (); public Date getDateOfFirstMarriage ();}  

    Mỗi người đều có một cái tên. Do đó, sẽ không hợp lý nếu trường name 'không có giá trị nào được liên kết với nó'. Trường name không được để trống. Việc gán null cho nó là bất hợp pháp.

    Mặt khác, trường dateOfFirstMarriage không đại diện cho một giá trị bắt buộc. Không phải ai cũng kết hôn. Do đó, điều hợp lý khi dateOfFirstMarriage 'không có giá trị nào được liên kết với nó'. Do đó, dateOfFirstMarriage là một trường có thể vô hiệu hóa. Nếu trường dateOfFirstMarriage của một người trỏ đến null thì điều đó đơn giản có nghĩa là người này chưa bao giờ kết hôn.

    Lưu ý: Rất tiếc, hầu hết các ngôn ngữ lập trình phổ biến không ' t phân biệt giữa kiểu nullable và không thể nullable. Không có cách nào để tuyên bố một cách đáng tin cậy rằng null không bao giờ có thể được gán cho một tham chiếu đối tượng nhất định. Trong một số ngôn ngữ, có thể sử dụng chú thích, chẳng hạn như chú thích không chuẩn @Nullable và @NonNullable trong Java. Đây là một ví dụ:

      interface Person {public @Nonnull String getName (); public @Nullable Date getDateOfFirstMarriage ();}  

    Tuy nhiên, những chú thích như vậy không được trình biên dịch sử dụng để đảm bảo an toàn không. Tuy nhiên, chúng vẫn hữu ích cho người đọc và chúng có thể được sử dụng bởi các IDE và các công cụ như máy phân tích mã tĩnh.

    Điều quan trọng cần lưu ý là không nên sử dụng null để biểu thị các điều kiện lỗi.

    Hãy xem xét một hàm đọc dữ liệu cấu hình từ một tệp. Nếu tệp không tồn tại hoặc trống, thì cấu hình mặc định sẽ được trả lại. Đây là chữ ký của hàm:

      public Config readConfigFromFile (Tệp tin)  

    Điều gì sẽ xảy ra trong trường hợp lỗi đọc tệp?

    < p> Chỉ cần trả về null ?

    KHÔNG!

    Mỗi ngôn ngữ có cách tiêu chuẩn riêng để báo hiệu các điều kiện lỗi và cung cấp dữ liệu về lỗi, chẳng hạn như mô tả, loại, dấu vết ngăn xếp, v.v. Nhiều ngôn ngữ (C #, Java, v.v.) sử dụng cơ chế ngoại lệ và các ngoại lệ nên được sử dụng trong các ngôn ngữ này để báo hiệu lỗi thời gian chạy. readConfigFromFile không được trả về null để biểu thị lỗi. Thay vào đó, chữ ký của hàm nên được thay đổi để làm rõ rằng hàm có thể bị lỗi:

      public Config readConfigFromFile (File file) ném IOException  

    Hãy nhớ:

    Chỉ cho phép null nếu tham chiếu đối tượng 'không có giá trị nào được liên kết với nó'.

    Không sử dụng null để báo hiệu các điều kiện lỗi.

    Null-safe

    Hãy xem xét đoạn mã sau:

      String name = null; int l = name.length ();  

    Tại thời điểm chạy, đoạn mã trên dẫn đến lỗi con trỏ null khét tiếng , bởi vì chúng tôi cố gắng thực thi một phương thức tham chiếu trỏ đến null . Ví dụ: trong C #, một NullReferenceException được ném ra, trong Java, nó là NullPointerException .

    Lỗi con trỏ null thật khó chịu.

    Đây là lỗi thường gặp nhất trong nhiều ứng dụng phần mềm và là nguyên nhân gây ra vô số rắc rối trong lịch sử phát triển phần mềm. Tony Hoare, người phát minh ra null , gọi đó là 'sai lầm hàng tỷ đô la'.

    Nhưng Tony Hoare (người đoạt giải Turing năm 1980 và là người phát minh ra thuật toán Quicksort), cũng đưa ra gợi ý giải pháp trong speech :

    Các ngôn ngữ lập trình gần đây hơn… đã giới thiệu các khai báo cho các tham chiếu không rỗng. Đây là giải pháp mà tôi đã từ chối vào năm 1965.

    Trái với một số suy nghĩ thông thường, thủ phạm không phải là null per se. Vấn đề là thiếu hỗ trợ xử lý null trong nhiều ngôn ngữ lập trình. Ví dụ: tại thời điểm viết bài (tháng 5 năm 2018), không có ngôn ngữ nào trong số mười ngôn ngữ hàng đầu trong chỉ mục Tiobe nguyên bản phân biệt giữa loại có thể null và không thể null.

    < p> Do đó, một số ngôn ngữ mới cung cấp sự an toàn trong thời gian biên dịch và cú pháp cụ thể để xử lý thuận tiện null trong mã nguồn. Trong các ngôn ngữ này, đoạn mã trên sẽ dẫn đến lỗi thời gian biên dịch. Chất lượng và độ tin cậy của phần mềm tăng lên đáng kể vì lỗi con trỏ null biến mất một cách thú vị.

    An toàn không có giá trị là một chủ đề hấp dẫn xứng đáng có bài viết riêng của nó.

    Hãy nhớ:

    Bất cứ khi nào có thể, hãy sử dụng ngôn ngữ hỗ trợ null-an toàn khi biên dịch.

    Lưu ý: Một số ngôn ngữ lập trình (chủ yếu là ngôn ngữ lập trình chức năng như Haskell) không hỗ trợ khái niệm null . Thay vào đó, họ sử dụng Có thể / Mẫu tùy chọn để thể hiện "không có giá trị". Trình biên dịch đảm bảo rằng trường hợp "không có giá trị" được xử lý một cách rõ ràng. Do đó, lỗi con trỏ rỗng không thể xảy ra.

    Tóm tắt

    Dưới đây là tóm tắt các điểm chính cần nhớ:

    • Nếu a tham chiếu đến null , điều đó luôn có nghĩa là không có giá trị nào được liên kết với nó.
    • Trong hầu hết các trường hợp, null có một ý nghĩa cụ thể hơn phụ thuộc vào theo ngữ cảnh.
    • Nếu chúng ta cần biết tại sao không có giá trị nào được liên kết với tham chiếu, thì dữ liệu bổ sung phải được cung cấp để phân biệt các trường hợp có thể xảy ra.
    • Cho phép null chỉ khi một tham chiếu đối tượng 'không có giá trị nào được liên kết với nó' là hợp lý.
    • Không sử dụng null để báo hiệu các điều kiện lỗi.
    • Khái niệm null chỉ tồn tại cho các loại tham chiếu. Nó không tồn tại cho các loại giá trị.
    • Trong một số ngôn ngữ, null là giá trị mặc định cho các loại tham chiếu.
    • null hoạt động cực kỳ nhanh và rẻ.
    • Bất cứ khi nào có thể, hãy sử dụng ngôn ngữ hỗ trợ biên dịch-time-null-safe.


Xem thêm những thông tin liên quan đến chủ đề null lúc null là gì

Statistical Significance, the Null Hypothesis and P-Values Defined & Explained in One Minute

  • Tác giả: One Minute Economics
  • Ngày đăng: 2018-02-13
  • Đánh giá: 4 ⭐ ( 6596 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: We shouldn't accept the conclusions of let's say a study before also thinking about whether or not the findings are statistically significant.

    Statistical significance may seem like a prohibitively complex term but in reality, determining whether or not findings are statistically significant isn't that difficult.

    As we're about to find out, it's ultimately all a matter of accepting or rejecting the null hypothesis we start with and calculating p-values. And fortunately, calculating p-values won't be something you have to do by hand 🙂

    Please like, comment and subscribe if you've enjoyed the video.

    To support the channel, give me a minute (see what I did there?) of your time by visiting OneMinuteEconomics.com and reading my message.

    Bitcoin donations can be sent to 1AFYgM8Cmiiu5HjcXaP5aS1fEBJ5n3VDck and PayPal donations to oneminuteeconomics@gmail.com, any and all support is greatly appreciated!

    Oh and I've also started playing around with Patreon, my link is:

    https://www.patreon.com/oneminuteeconomics

    Interested in reading a good book?

    My first book, Wealth Management 2.0 (through which I do my best to help people manage their wealth properly, whether we're talking about someone who has a huge amount of money at his disposal or someone who is still living paycheck to paycheck), can be bought using the links below:

    Amazon - https://www.amazon.com/Wealth-Management-2-0-Financial-Professionals-ebook/dp/B01I1WA2BK

    Barnes & Noble - http://www.barnesandnoble.com/w/wealth-management-20-andrei-polgar/1124435282?ean=2940153328942

    iBooks (Apple) - https://itun.es/us/wYSveb.l

    Kobo - https://store.kobobooks.com/en-us/ebook/wealth-management-2-0

    My second book, the Wall Street Journal and USA Today bestseller The Age of Anomaly (through which I help people prepare for financial calamities and become more financially resilient in general), can be bought using the links below.

    Amazon - https://www.amazon.com/Age-Anomaly-Spotting-Financial-Uncertainty-ebook/dp/B078SYL5YS

    Barnes & Noble - https://www.barnesandnoble.com/w/the-age-of-anomaly-andrei-polgar/1127084693?ean=2940155383970

    iBooks (Apple) - https://itunes.apple.com/us/book/age-anomaly-spotting-financial-storms-in-sea-uncertainty/id1331704265

    Kobo - https://www.kobo.com/ww/en/ebook/the-age-of-anomaly-spotting-financial-storms-in-a-sea-of-uncertainty

    Last but not least, if you'd like to follow me on social media, use one of the links below:

    https://www.facebook.com/oneminuteeconomics

    https://twitter.com/andreipolgar

    https://ro.linkedin.com/in/andrei-polgar-9a11a561

Null là gì

  • Tác giả: hocviencanboxd.edu.vn
  • Đánh giá: 5 ⭐ ( 1063 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: Null là gì | Hocviencanboxd.edu.vn

Sự khác biệt giữa NULL, '\ 0' và 0 là gì?

  • Tác giả: qastack.vn
  • Đánh giá: 3 ⭐ ( 9534 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: [Tìm thấy giải pháp!] Lưu ý: Câu trả lời này áp dụng cho ngôn ngữ C, không phải C ++.…

Null là gì và cấu trúc từ Null trong câu Tiếng Anh

  • Tác giả: www.studytienganh.vn
  • Đánh giá: 5 ⭐ ( 7640 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: Website học Tiếng Anh online trực tuyến số 1 tại Việt Nam. Hơn 14000+ câu hỏi, 500+ bộ đề luyện thi Tiếng Anh có đáp án.Truy cập ngay chỉ với 99k/ 1 năm, Học Tiếng Anh online thoải mái không giới hạn tài liệu

Null là gì? ý nghĩa của từ Null

  • Tác giả: duhocmyau.edu.vn
  • Đánh giá: 4 ⭐ ( 4381 lượt đánh giá )
  • Khớp với kết quả tìm kiếm:

[Tự học C++] Tìm hiểu về con trỏ NUll(Null pointers) trong C++

  • Tác giả: cafedev.vn
  • Đánh giá: 3 ⭐ ( 6028 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: Giống như các biến thông thường, con trỏ cũng không được khởi tạo khi chúng được thể hiện/khai báo (instantiated). Trừ khi có một giá trị được gán, nếu không thì con trỏ sẽ trỏ đến một số địa chỉ rác theo mặc định.

Null là gì? Cách kiểm tra null trong Java như thế nào?

  • Tác giả: reviewaz.vn
  • Đánh giá: 5 ⭐ ( 2379 lượt đánh giá )
  • Khớp với kết quả tìm kiếm: Từ Null- từ ngữ được sử dụng nhiều trong các lĩnh vực khác nhau với nội dung đa dạng. Vậy Null là gì? Có ý nghĩa gì đặc biệt trong Java? cùng tìm hiểu nhé

Xem thêm các bài viết khác thuộc chuyên mục: Kiến thức lập trình

Xem Thêm  Cách chèn GIF vào email HTML - cách chèn html gif