F# 的 char 类型是一个 16 位值,用来表示文本中最小的可寻址单位,默认不可变。
char可以用单引号定义为字面量:
let ch = 'A'
// => val ch: char = 'A'
字符串就是一串字符。
通过从 0 开始的下标,可以从字符串中取出单个char:
"Exercism"[4] // => 'c'
遍历字符串时,每一步都会返回一个char。
下一个例子为了简便,用到了高阶函数和匿名函数。 教学大纲后面会详细介绍它们,现在你只需要知道,它们本质上是一种简洁的写法,用来遍历字符串中的字符。
Seq.map (fun c -> c, int c) "F#" // => [('F', 70); ('#', 35)]
如上所示,char可以转换成它的int值。
这对其他文字(至少在有些情况下)也成立:
Seq.map (fun c -> c, int c) "東京" // => [('東', 26481); ('京', 20140)]
比较字符时,用的是底层的 Int16:
'A' < 'D' // => true
反过来,int也可以转换成char:
char 77 // => 'M'
System.Char 库包含了 .NET 语言应有的全套方法,比如大小写转换:
'a' |> System.Char.ToUpper // => 'A'
'Q' |> System.Char.ToLower // => 'q'
在本练习中,你将实现一部分实用工具函数,帮助开发者清理标识符名称。
在 6 个任务里,你将逐步构建两个函数:transform用来转换单个字符,clean用来转换字符串。
合法的标识符由零个或多个字母、下划线、连字符、问号和表情符号组成。
如果把空字符串传给clean函数,就应该返回空字符串。
实现transform函数,把连字符替换为下划线。
transform '-' // => "_"
移除所有空白字符。 这包括开头和结尾的空白。
transform ' ' // => ""
修改transform函数,把 camelCase 转换为 kebab-case
transform 'D' // => "-d"
修改transform函数,省略所有数字字符。
transform '7' // => ""
修改transform函数,把 'α' 到 'ω' 范围内的希腊字母替换掉。
transform 'β' // => "?"
实现clean函数,对整个字符串应用这些操作。
不符合这些规则的字符应原样保留。
clean " a2b Cd-ω😀 " // => "ab-cd_?😀"
这个主题会在教学大纲的后面详细讲解。
不过现在,知道有一个叫 String.collect 的高阶函数可能会很有用,它会用你提供的函数,把 char 的集合转换成字符串。
let transform ch = $"{ch}_"
String.collect transform "abc" // => "a_b_c_"