F # Options ... do they really prevent Null Reference Exceptions

I am reading the book "Professional F # 2.0". The author shows the following code

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

then say

"this makes using an option far superior to using a null value and makes a long way to remove a significant source of runtime exceptions"

OK. so i write

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

And I get

System.NullReferenceException: An object reference is not set to an object instance. in System.Object.GetType () at. $ FSI_0008.main @ () Stopped due to an error

And I love "un !!!"

How is it really done

 if a.isSome then do bla bla any different from if a != null then do bla bla 

So, I do not see how the programmer is saved from NullPointers

PS: NullPointerException in the past caused a lot of grief.

+6
source share
2 answers

To add to Thomas's answer, the main advantage of the Option type is the higher-order functions that it supports, which gives you more brevity and security. You can find my blog post helpful.

+4
source

The F # compiler will not prevent you from completely NullReferenceException . When you work with types defined in .NET, you can still get null because F # cannot prevent this.

However, when you work with types declared in F #, then the compiler does not allow you to create null values โ€‹โ€‹of this type, and therefore it avoids a NullReferenceException in this case. For example, the following code does not compile:

 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 

When you use option<Person> as an argument, you should explicitly check for None and Some cases. This is best done with match , which checks that you have not missed any of these cases. For instance:

 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 

A warning tells you that you must add None case handling. You can still compile the code, but you will not get a NullReferenceException when working with F # types unless you ignore the warnings.

See also fooobar.com/questions/3563 / ....

+9
source

Source: https://habr.com/ru/post/919678/


All Articles