Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
551 views
in Technique[技术] by (71.8m points)

f# - How to implement Singleton Pattern (syntax)

I have a cache of data which is getting refreshed from an outside source, and I want to limit my access tot his cache (readonly) inside of my app. I don't want to have refresh the datasource everytime I need access to it (ie. on instantiation go and pull all the data I need, as there is quite a bit of data that is being kept up to date).

type MySingleton = 

        [<DefaultValue>]
        static val mutable private instance: MySingleton

        static member GetInstance() = 
            instance

I guess this is one of the gotchas about implementing a project and trying to learn the language at the same time. I know the logic needs to be

if instance is null
    synchronize
    if instance is null
        instance = new MySingleton()

but the lack of null is throwing me for a loop. I think I can use an option type etc but it is throwing me for a loop

type MySingleton = 

        [<DefaultValue>]
        static val mutable private instance: MySingleton option

        static member GetInstance() = 
            match instance with
                 | Some(i) -> i
                 | None -> 
                            *MySingleton.instance = new MySingleton()
                            MySingleton.instance*

that logic is wrong according to the compiler...

       if Helper.notExists MySingleton.instance then
            MySingleton.instance <- Some(new MySingleton())        
       MySingleton.instance 

should I be using IF statements instead? Is there a prefered pattern for this syntax in f#?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Both .NET 4.0 and F# have Lazy, so I think you want

module MySingleton =
    let private x = Lazy.Create(fun() -> 42)
    let GetInstance() = x.Value

(where 42 might be a new WhateverType() or whatever the expensive initialization is).

http://msdn.microsoft.com/en-us/library/dd997286.aspx

(Commentary: It's 2010, and getting rare to have to explicitly deal with synchronization primitives; languages and libraries are encapsulating all the common patterns.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...