F# 伤了我的脑……谁能帮忙把 C# 翻译成 F# 吗?

发布于 2024-12-12 05:33:08 字数 741 浏览 0 评论 0原文

我发现了一个我认为非常适合学习 F# 的快速项目。然而,出于某种原因,我就是无法全神贯注于它。经过几个小时的教程甚至一些电影之后我仍然...不明白。

因此,我想开始使用企业管理器“生成脚本”对工作中的存储过程进行版本控制,并希望清空脚本日期。我放弃了,用 C# 做了,但现在我真的很好奇,希望能得到一些见解。

我并不是完全空手而归,这是我的 C# 代码:

string path = @"C:\Subversion\CompanyName\SQL\DBName";
string fileSpec = "*.sql";
string pattern = @"Script Date: \d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}";
string replace = "Script Date: ";

foreach (var file in Directory.EnumerateFiles(path, fileSpec))
{
    string content = File.ReadAllText(file);

    content = Regex.Replace(content, pattern, replace);

    File.WriteAllText(file, content, Encoding.Unicode);
}

我猜 F# 中有一些看起来很酷的 2-3 行解决方案...我很想看到它。

谢谢你的提示!我已经更新了它以匹配下面正在做的事情,使视觉比较可能更具启发性。下面的评论也很棒。

I found a quick project I thought would be perfect for learning F#. However I just cannot wrap my brain around it for some reason. After hours of tutorials and even some movies I still just... don't get it.

So I wanted to start versioning our stored procedures at work using Enterprise Manager "Generate Scripts" and wanted to blank out the script date. I gave up and did it in C# but now I'm REALLY curious and am hoping for some insight.

I am not completely empty handed, here is my C# code:

string path = @"C:\Subversion\CompanyName\SQL\DBName";
string fileSpec = "*.sql";
string pattern = @"Script Date: \d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}";
string replace = "Script Date: ";

foreach (var file in Directory.EnumerateFiles(path, fileSpec))
{
    string content = File.ReadAllText(file);

    content = Regex.Replace(content, pattern, replace);

    File.WriteAllText(file, content, Encoding.Unicode);
}

I am guessing there is some cool looking 2-3 line solution in F#... I'd love to see it.

Thx for the tips! I have updated it to match what is being done below to make the visual comparison potentially more enlightening. Also great comments below.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱已欠费 2024-12-19 05:33:08
let path = @"C:\Subversion\CompanyName\SQL\DBName"
let fileSpec = "*.sql"
let pattern = @"Script Date: \d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}"
let replace = "Script Date: "

Directory.EnumerateFiles (path, fileSpec)
|> Seq.iter (fun file ->
    let content = Regex.Replace (File.ReadAllText file, pattern, replace)
    File.WriteAllText (file, content, Encoding.Unicode))

请注意,您的 C# 代码is编辑:曾经)也比必要的更加冗长。

let path = @"C:\Subversion\CompanyName\SQL\DBName"
let fileSpec = "*.sql"
let pattern = @"Script Date: \d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}"
let replace = "Script Date: "

Directory.EnumerateFiles (path, fileSpec)
|> Seq.iter (fun file ->
    let content = Regex.Replace (File.ReadAllText file, pattern, replace)
    File.WriteAllText (file, content, Encoding.Unicode))

Note that your C# code is (EDIT: was) also far more verbose than necessary.

面犯桃花 2024-12-19 05:33:08

您所需要做的几乎就是用 let 关键字替换变量声明中的类型名称(在 C# 中可以编写 var),删除所有分号和大括号,然后将 foreach 替换为
对于文件中的文件执行。您还使用了一些命名空间,因此在 F# 中,您需要类似以下内容:

open System.IO
open System.Text.RegularExpressions

您正在使用一个可变变量 (content),但您实际上并不需要更改它。您可以仅使用不同的变量(例如newContent)来存储替换结果。因此,中间部分将是:

let content = File.ReadAllText(file)  // No need for a stream reader here!

let pattern = @"Script Date: \d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}"
let replace = "Script Date: "    
let newContent = Regex.Replace(content, pattern, replace)

您还可以使用相同的变量名称,这意味着您正在声明一个新的(不可变的)变量,该变量隐藏了作用域其余部分中的前一个变量(请参阅此 SO 答案以获取更多信息

我还会更改最后一位(即使在 C# 中!)以关闭流,即使发生异常。在 C# 中,您可以使用 using。要在 F# 中编写相同的内容,您可以使用 use 关键字:

use fileStream = new FileStream(file, FileMode.Truncate, FileAccess.Write, FileShare.None)
use writer = new StreamWriter(fileStream, Encoding.Unicode)
writer.Write(content)
writer.Flush()

use 关键字确保对象在超出范围时被释放(关闭) - 即,在 for 循环迭代结束时(在本例中)。

Pretty much all you need to do is to replace type name in variable declarations (where you could write var in C#) with the let keyword, remove all semicolons and curly braces and replace foreach with
for file in files do. You're also using some namespaces, so in F#, you need something like:

open System.IO
open System.Text.RegularExpressions

You're using one mutable variable (content), but you don't really need to mutate it. You can just use a different variable (such as newContent) to store the result of replacement. So, the middle part will be:

let content = File.ReadAllText(file)  // No need for a stream reader here!

let pattern = @"Script Date: \d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}"
let replace = "Script Date: "    
let newContent = Regex.Replace(content, pattern, replace)

You could also use the same variable name, which means that you're declaring a new (immutable) variable that hides the previous one in the rest of the scope (see this SO answer for more information)

I would also change the last bit (even in C#!) to close the stream even if an exception occurs. In C#, you would use using. To write the same thing in F#, you can use the use keyword:

use fileStream = new FileStream(file, FileMode.Truncate, FileAccess.Write, FileShare.None)
use writer = new StreamWriter(fileStream, Encoding.Unicode)
writer.Write(content)
writer.Flush()

The use keyword ensures that the object is disposed (closed) when it goes out of scope - that is, at the end of the for loop iteration (in this case).

榆西 2024-12-19 05:33:08

琐碎的。编译。在反射器中打开。选择反编译语言为F#。

Trivial. Compile. Open in Reflector. Choose decompiler language to F#.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文