我有一个练习,要求使用一个函数将字符串的所有字符转换为大写
System.Char.ToUpper
Run Code Online (Sandbox Code Playgroud)
首先,我将字符串更改为char数组,并将数组更改为字符列表
let x = s.ToCharArray()
List.ofArray x
Run Code Online (Sandbox Code Playgroud)
接下来,我想我会使用List.iter迭代我的列表并在每个字符上使用System.Char.ToUpper函数.
List.iter (fun z -> (System.Char.ToUpper(z)))
Run Code Online (Sandbox Code Playgroud)
但这不起作用.我得到一个错误'表达式应该有单位,但这里有char.' 我究竟做错了什么?它是逻辑或语法的缺陷吗?
这需要一些拆包.
首先,你的核心错误:System.Char.ToUpper是一个功能.它需要一个char并返回另一个char.它不会以某种方式将其参数" 更新 "为新值.
let x = 'a'
let y = System.Char.ToUpper x // y = 'A', x = 'a'.
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我给出y了函数结果的名称.值的值y是'A',但值x仍然是'a'.调用该函数后,x没有改变.
从这个错误中,其余的都是如此.
其次,List.iter是一个函数,对于列表的每个元素,都会使某些事情"发生".它不会用新的东西替换列表的每个元素,也不会创建新的列表.它只是让每个元素都有所发生.这种" 东西 " 的最简单的例子是打印到控制台:
List.iter (fun x -> printfn "%i" x) [1; 2; 3] // Prints "1", then "2", then "3"
Run Code Online (Sandbox Code Playgroud)
请注意,此函数有两个参数:表示需要发生的事情的函数,以及从中获取元素的列表.在你的问题中,你似乎错过了第二个论点.怎么List.iter知道使用哪个列表?
第一个参数List.iter需要是一个返回的函数unit.这是F#中的一种特殊类型,基本上意味着"没有价值".当函数没有返回值时,这意味着调用它的唯一原因是使外部事件发生(在函数式编程中称为" 副作用 ").这就是为什么List.iter要求函数返回unit- 这是额外的保护,以免意外提供错误的功能,就像你一样,实际上:你提供的功能返回char.这就是您收到错误的原因.
第三,就像使用一样ToUpper,调用List.ofArray不会以某种方式"更新" x为列表.相反,它返回一个列表.如果你没有给返回的列表一个名字,它就会丢失.这意味着你打电话的方式List.ofArray是徒劳的.
你真正需要的是(1)获取你的字符串中的字符序列,然后(2)将它转换为一个新的序列,其中每个字符都是大写,然后(3)将这些字符粘合在一起以获得一个新的字符串.
步骤(1)是无操作,因为.NET字符串已经是字符序列(即它们实现IEnumerable<char>).步骤(2)通过称为的通用操作完成Seq.map.这是一个通过将给定函数应用于每个元素将序列转换为新序列的操作.在这种情况下,"给定的功能"将是System.Char.ToUpper.步骤(3)可以通过String.concat,但你需要首先将每个字符串转换为字符串,因为String.concat需要一系列字符串,而不是字符.
let chars = s
let upperChars = Seq.map System.Char.ToUpper chars
let strChars = Seq.map string upperChars
let result = String.concat "" strChars
Run Code Online (Sandbox Code Playgroud)
或者这可以用更短的方式完成,而不是给每个步骤的结果一个单独的名称,而是通过将每个结果直接传递到下一个操作:
let result =
s
|> Seq.map System.Char.ToUpper
|> Seq.map string
|> String.concat ""
Run Code Online (Sandbox Code Playgroud)
最后,实际上有一个更短的方法,但它是如此荒谬明显,感觉就像作弊.
问题是,因为字符串是序列,所以对它们进行所有序列操作都是有意义的.你猜怎么着?他们是这样!具体来说,有一个函数String.map,它执行相同的操作Seq.map,但对于字符串:
let result = String.map System.Char.ToUpper s
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1438 次 |
| 最近记录: |