7

「Professional F# 2.0」という本を読んでいます著者は次のコードを示しています

let a string : option = None
if a.IsNone then
    System.Console.WriteLine("a is none")
else
    System.Console.WriteLine("a is some");;

それから言う

「これにより、Option の使用が null の使用よりもはるかに優れたものになり、実行時にスローされる例外の重要な原因を取り除くのに大いに役立ちます」

わかった。だから私は書く

System.Console.WriteLine(a.GetType());;

そして、私は得る

System.NullReferenceException: オブジェクト参照がオブジェクトのインスタンスに設定されていません。System.Object.GetType() で .$FSI_0008.main@() で エラーのため停止しました

そして、私は「ウン!!!」のようです。

実際にどうやって

if a.isSome then
    do bla bla

any different from

if a != null then
   do bla bla

したがって、プログラマーが NullPointers からどのように保存されているのかわかりません

PS: NullPointerException は、過去に多くの悲しみをもたらしました。

4

2 に答える 2

9

F# コンパイラが完全に防止するわけではありませんNullReferenceException。.NET で定義された型を使用する場合でも、null値を取得できます。これは、F# でそれを防ぐ方法がないためです。

ただし、F# で宣言された型を操作する場合、コンパイラはその型の値の作成を許可しないため、その場合nullは回避NullReferenceExceptionされます。たとえば、次のコードはコンパイルされません。

type Person(name:string) = 
  member x.Name = name

// 'Person' is a type declared in F#, so the argument cannot be 'null' in safe code
let printName (person:Person) = 
  printfn "%s" person.Name

// Compiler error here - 'null' is not a valid value of 'Pereson' type
printName null

引数として使用する場合は、 and のケースoption<Person>を明示的にチェックする必要があります。これは、どのケースも見逃していないかをチェックする を使用して行うのが最適です。例えば:NoneSomematch

let printName (person:option<Person>) = 
  match person with
  // You get a warning here, saying that you're not handling the 'None' case!
  | Some person -> printfn "%s" person.Name

この警告は、 case handling を追加する必要があることを示していますNone。コードをコンパイルすることはできますが、NullReferenceException警告を無視しないと、F# 型を操作するときに取得できません。

関連する素晴らしい StackOverflow の投稿も参照してください。

于 2012-07-04T13:58:07.267 に答える
5

Tomas の回答に加えて、型の主な利点は、Option型がサポートする高次関数にあり、簡潔さと安全性が向上します。このトピックに関する私のブログ投稿が役に立つかもしれません。

于 2012-07-04T19:09:35.193 に答える