F#:[<StructuredFormatDisplay>] 与覆盖 __.ToString()。¿有什么问题吗?

San*_*nti 5 f# attributes record tostring

dotnet 2.2.203 上下文:在Ubuntu 18.04 桌面计算机上的容器化环境中运行 F#

问题:StructuredFormatDisplay组合记录中的 不起作用。是不是错了?这是代码

[<StructuredFormatDisplay("{SizeGb}GB")>]
type Disk = 
    { SizeGb : int }
    override __.ToString() = sprintf "<%dGB>" __.SizeGb

[<StructuredFormatDisplay("Computer #{Id}: {Manufacturer}/{DiskCount}:{Disks}")>]
type Computer =
    { Id: int
      mutable Manufacturer: string
      mutable Disks: Disk list }
      override __.ToString() = sprintf "#%d<%s>%O" __.Id __.Manufacturer __.Disks


[<EntryPoint>]
let main argv =

    let myPc =
        { Id = 0
          Manufacturer = "Computers Inc."
          Disks =
            [ { SizeGb = 100 }
              { SizeGb = 250 }
              { SizeGb = 500 } ] }

    printfn "%%O = %O" myPc 
    printfn "%%A = %A" myPc   
    0
Run Code Online (Sandbox Code Playgroud)

和输出

%O = #0<Computers Inc.>[<100GB>; <250GB>; <500GB>]
%A = Computer #0: Computers Inc./3:[...GB; ...GB; ...GB]
Run Code Online (Sandbox Code Playgroud)

计算机记录中磁盘记录的 %A 模式只是打印一些...点!

但 %O 打印得很好。

Ngh*_*Bui 3

我确认这个问题也发生在我的环境中。

当直接在磁盘列表上打印 %A 时,输出是可以的:

printfn "%A" [{SizeGb = 10}] // output: [10GB]
Run Code Online (Sandbox Code Playgroud)

但是,当像代码中那样间接打印磁盘列表时:

[<StructuredFormatDisplay("Computer #{Id}: {Manufacturer}/{DiskCount}:{Disks}")>]
Run Code Online (Sandbox Code Playgroud)

我们收到点。

我认为这是 F# 核心库的一个错误。一种解决方法可能是添加一个新的字符串属性来保存磁盘列表的格式化字符串,然后使用该属性:

[<StructuredFormatDisplay("Computer #{Id}: {Manufacturer}/{DiskCount}:{DisksStr}")>]
type Computer =
{ Id: int
  mutable Manufacturer: string
  mutable Disks: Disk list }
  member this.DisksStr = sprintf "%A" this.Disks
Run Code Online (Sandbox Code Playgroud)

  • 谢谢@Nghia,你的代码是一个很好的解决方法,但最后是一个解决方法。如果这是核心库上的真正错误,我们必须提出问题。等待用其他答案来确认这一点。 (3认同)