代码之家  ›  专栏  ›  技术社区  ›  Tomas Jansson

如何在fsharp的对象表达式中使用“member val”?

f#
  •  2
  • Tomas Jansson  · 技术社区  · 7 年前

    我在F#中有一个接口(由某个typescript生成),如下所示:

    type [<AllowNullLiteral>] AppOptions =
        abstract credential: Admin.Credential.Credential option with get, set
        abstract databaseAuthVariableOverride: Object option with get, set
        abstract databaseURL: string option with get, set
        abstract storageBucket: string option with get, set
        abstract projectId: string option with get, set
    

    我以为创建这种类型的实例的最简单方法是创建一个简单的对象表达式,但是我无法使它工作。不是 member val 在对象表达式中允许吗?如果不是,那么在所有属性上使用getter和setter创建接口的简单实例的最简单方法是什么?这是我尝试过的,但没有成功:

    let options = 
        { new Admin.AppOptions with
            member val credential: Admin.Credential.Credential option = None with get, set 
            member val databaseAuthVariableOverride: obj option = None with get, set 
            member val databaseURL: string option = None with get, set 
            member val databaseURL: string option = None with get, set 
            member val projectId: string option = None with get, set 
        }      
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   7sharp9    7 年前

    我认为成员var不在对象表达式规范中,只允许使用这样的长表单属性:

    let options =
        let mutable credential = None 
        let mutable databaseAuthVariableOverride = None
        let mutable databaseURL = None
        let mutable storageBucket = None
        let mutable projectId = None
        { new AppOptions with
            member x.credential with get() = credential and set v = credential <- v
            member x.databaseAuthVariableOverride with get() = databaseAuthVariableOverride and set v = databaseAuthVariableOverride <- v
            member x.databaseURL with get() = databaseURL and set v = databaseURL <- v
            member x.storageBucket with get() = storageBucket and set v = storageBucket <- v
            member x.projectId with get() = projectId and set v = projectId <- v
        } 
    

    编译器会像这样投射C类代码:

    [assembly: FSharpInterfaceDataVersion(2, 0, 0)]
    [assembly: AssemblyVersion("0.0.0.0")]
    [CompilationMapping(SourceConstructFlags.Module)]
    public static class _
    {
        [Serializable]
        [AllowNullLiteral]
        [CompilationMapping(SourceConstructFlags.ObjectType)]
        public interface AppOptions
        {
            override FSharpOption<object> credential
            {
                get;
                set;
            }
    
            override FSharpOption<object> databaseAuthVariableOverride
            {
                get;
                set;
            }
    
            override FSharpOption<string> databaseURL
            {
                get;
                set;
            }
    
            override FSharpOption<string> storageBucket
            {
                get;
                set;
            }
    
            override FSharpOption<string> projectId
            {
                get;
                set;
            }
        }
    

    See sharplab

    正常类型在这里可能更简洁:

        type t() = 
         interface AppOptions with
             member val credential = None with get, set
             member val databaseAuthVariableOverride = None with get, set 
             member val databaseURL = None with get, set 
             member val storageBucket = None with get, set 
             member val projectId = None with get, set