为什么 Console.Readline 不起作用但 Console.Readline() 能够正常运行?

11

在 F# 中如何使用 Console.Readline?与 Console.Writeline 不同,当我调用它时它并没有被执行。

4个回答

31
如果您使用

let s = Console.ReadLine

您仅在构建指向ReadLine函数的委托。您需要声明:

let s = Console.ReadLine()

要实际执行该函数。这就像C#语法一样,不同的是类型推断意味着您不会收到编译器警告。


4
是的。Console.ReadLine是一个“单位->字符串”值。通过添加括号,您将作为参数传递它所期望的“单位”。 - YotaXP
+1 - 通过在()前面要求空格,就像对函数的任何其他参数一样,可以使此行为更清晰。 - Robert Jeppesen
2
你会得到一个编译器警告!当你使用 s 时。听起来你的意思是写 Console.ReadLine() |> ignore。我认为这是 C# 没有检查函数输出是否被捕获或忽略的问题。 - Arturo Hernandez

9
“it isn't being honored”是什么意思?这是我在VS2010b1中刚刚编写的一个小控制台应用程序,它可以正常工作:
open System

let line = Console.ReadLine()
Console.WriteLine("You wrote {0}", line)

// Just to make it pause
let unused = Console.ReadLine()

您是否尝试在Visual Studio中使用F# Interactive运行代码?如果是,那可能就是问题所在,正如Brian的帖子所解释的那样。

但是,当我使用命令行中的F# Interactive时,我没有看到同样的问题。以下是一个完整的会话记录:

Microsoft F# Interactive, (c) Microsoft Corporation, All Rights Reserved
F# Version 1.9.6.16, compiling for .NET Framework Version v4.0.20506

Please send bug reports to fsbugs@microsoft.com
For help type #help;;

> open System;;
> let line = Console.ReadLine();;
Hello world

val line : string = "Hello world"

从 F# 交互环境中运行 Brian 的循环代码并没有展现同样的问题。

总之: 看起来在 Visual Studio 的 F# 交互环境中出现了故障,但是在命令行交互模式或完整控制台应用程序中交互运行时没有出现该问题。


嗯...这很奇怪。这是安装在VS2010b1中的版本吗? - Jon Skeet
我想通了。"Console.ReadLine()" 可以用。"Console.ReadLine" 被静默忽略,因为它只是在构建一个委托。 - Jonathan Allen
我也是。我习惯于VB,其中括号是可选的,并且您必须指示何时需要函数本身。 - Jonathan Allen
啊...我想过可能是这样,但是觉得自己提出来有点傻 :) - Jon Skeet
2
"let unused = Console.ReadLine()" 用 F# 的语言风格更应该是 "Console.ReadLine() |> ignore" - 这样可以避免无用的 'let' 语句,同时忽略返回值。 - Erik Forbes
显示剩余4条评论

3

我手头没有Beta1的工具箱,但我知道过去我们曾经遇到过一个bug,即ReadLine()会看到在交互式UI和后台运行F#代码的进程之间通信的后台命令。可能有趣的是调查一下

let Foo max =
    let rec Loop i =
        if i < max then
            let line = System.Console.ReadLine() 
            printfn "line = %s" line
            Loop (i+1)
    Loop 1

Foo 12

当您将其突出显示并选择“发送到交互式”时,它会输出内容。我认为您可能会看到一些意外有趣的行,然后是您在窗口中键入的行。


1
是的,这看起来可能是问题所在:当我在beta1中尝试时,写出的第一行只是“line =”。 - Jon Skeet
区别在于你在ReadLine调用的末尾放置了空括号,而我没有。 - Jonathan Allen

-1

// 如果你不想使用 readline 返回的任何输入,那么这是正确的方法

Console.ReadLine() |> ignore


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接