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
1.0k views
in Technique[技术] by (71.8m points)

.net - Why does F#'s printfn work with literal strings, but not values of type string?

In the following F# code; I would expect that the printfn is being called three times; each with a string. However, the bottom line does not compile (The type 'string' is not compatible with the type 'Printf.TextWriterFormat<'a>').

What is it about the first two lines that means this can work? Aren't they just strings too?

open System

printfn ("
") // Works
printfn ("DANNY") // Works
printfn (DateTime.Now.ToLongTimeString()) // Doesn't compile
See Question&Answers more detail:os

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

1 Answer

0 votes
by (71.8m points)

The F# compiler statically analyses the format strings you pass to printfn to check that the arguments you pass are valid for the format specifiers you use. For example, the following does not compile:

printfn "%d" "some value"

since string is not compatible with the %d format specifier. The compiler converts valid format strings into a TextWriterFormat<T>.

It can't do this with arbitrary strings, and since it does not do the conversion, you get the type error above.

You can do the conversion yourself however using Printf.TextWriterFormat. For example, for a format string requiring a string and an int you can use:

let f = Printf.TextWriterFormat<string -> int -> unit>("The length of '%s' is: %d")
printfn f "something" 9

Since your string has no format placeholders, you can do:

let f = Printf.TextWriterFormat<unit>(DateTime.Now.ToLongTimeString())
printfn f

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

...