如何在F#中迭代字符串?

8

I've got the following F# code:

//Array iter version
let toSecureString (s:string) =
    let sString = new SecureString()
    s |> Array.iter (fun cl -> sString.AppendChar cl)
    sString

我试图将 .Net 字符串转换为 .Net SecureString。但当我尝试编译时,出现了类型不匹配的错误:
stdin(60,10): error FS0001: Type mismatch. Expecting a
    string -> 'a
but given a
    'b [] -> unit
The type 'string' does not match the type ''a []'

如果我没有指定s的类型,那么我看到的类型签名是这样的:
val toSecureString : char [] -> SecureString

但是我不想每次都手动创建一个char数组作为参数,这似乎缺少了什么。如何使得此代码能够接受传入的字符串参数?

如果有所不同,我正在测试 F# 2.0(Build 4.0.40219.1)。

欢迎任何提示。如果已经有人提出并解决了这个问题,请在评论中发布链接,我会关闭这个问题。


你为什么要使用 SecureString 呢?如果你已经有了一个 string,那么将其复制到 SecureString 中不会增加任何安全性。这可能就是为什么没有 AppendString() 方法的原因。 - svick
我正在使用SecureString,因为Windows API要求使用SecureString。 - Onorio Catenacci
哇,太棒了,三个优秀的答案。希望我能把它们全部选为“被接受的答案”。 - Onorio Catenacci
你在返回sString之前没有释放它吗? - Lee
你知道我曾经考虑过@Lee的观点。在FP中,你通常返回一个本地值的副本——这是默认的不可变性。但如果有问题,我会简单地将它改为"let"。我更感兴趣的是为什么Array.iter对我不起作用。 - Onorio Catenacci
显示剩余2条评论
3个回答

19
使用Seq.iter而不是Array.iter,因为字符串是char seq,而不是char[]

谢谢kvb。我知道我漏了什么明显的东西。 - Onorio Catenacci

5

要将字符串作为 char seq 操作,可以使用 String 模块。以下是正确的操作:

let toSecureString s =
    let sString = new SecureString()
    String.iter sString.AppendChar s
    sString

谢谢 @pad,我之前不知道那个选项。 - Onorio Catenacci
其实,我更喜欢使用String模块而不是Seq模块来避免类型注释 :)。 - pad
抱歉@pad-什么类型的注释?如果我使用Seq.iter,在上面的代码中,我不需要对s或cl进行类型规定。 - Onorio Catenacci
我的意思是避免明确地说sstring而不是seq<char>。你不必使用lambda,可以直接传递sString.AppendChar - pad
哦,我现在明白你的意思了。那是一个很好的观点。谢谢。 - Onorio Catenacci
1
当然,如果您使用Seq.iter并且删除类型注释,则该函数将适用于任何字符序列,而不仅仅是字符串。 - kvb

3
你还可以这样做:
SecureString(&&s.ToCharArray().[0], s.Length) 

谢谢@Daniel--这是第三种方法。我还有另一种方法,但没有发布。 - Onorio Catenacci

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