《scala编程实战》读书笔记------分隔字符串和字符串变量替换
一、 分隔字符串
说起分隔字符串我想各位大虾应该都不陌生,数据库操作很多会拼接”,”,”|”类似的很多字符,当然同理也会有很多解的方式,java当中常用的方法就是split。So,应该我猜到我要说的是什么了吧,scala当然也是split,但是scala有自己出彩的地方。接下来容我一一道来。
首先来一道开胃菜:
"hello world".split(" ").foreach(print)
很简单吧,以” ”(空格)分隔之后循环打印每个字符串,这看起来也没啥特别的,即使函数式也在之前的博客当中见到不少。接着往下说。
依旧,从代码说起:
"eggs, milk, butter, Coco Puffs".split(",").foreach(print) "eggs, milk, butter, Coco Puffs".split(",").map(_.trim).foreach(print) "eggs, milk, butter, Coco Puffs".split("\\s+").map(_.trim).foreach(print) "eggs, milk, butter, Coco Puffs".split(',').map(_.trim).foreach(print)
也许,猛一看,第二句代码好像和第四句代码是一样的,但实际上确不一样,为什么这么说呢,仔细观察split里面的字符串,发觉了吧,一个是双引号,一个是单引号,但他俩有什么本质区别?开始我看到此处的时候也不太明白,当然书籍后面也说明白了,来自于何处,但是即使这样没有直观感受也许说明不了问题,因此,来上一段源码。
/** Split this string around the separator character * * If this string is the empty string, returns an array of strings * that contains a single empty string. * * If this string is not the empty string, returns an array containing * the substrings terminated by the start of the string, the end of the * string or the separator character, excluding empty trailing substrings * * If the separator character is a surrogate character, only split on * matching surrogate characters if they are not part of a surrogate pair * * The behaviour follows, and is implemented in terms of <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split%28java.lang.String%29">String.split(re: String)</a> * * * @example {{{ * "a.b".split('.') //returns Array("a", "b") * * //splitting the empty string always returns the array with a single * //empty string * "".split('.') //returns Array("") * * //only trailing empty substrings are removed * "a.".split('.') //returns Array("a") * ".a.".split('.') //returns Array("", "a") * "..a..".split('.') //returns Array("", "", "a") * * //all parts are empty and trailing * ".".split('.') //returns Array() * "..".split('.') //returns Array() * * //surrogate pairs * val high = 0xD852.toChar * val low = 0xDF62.toChar * val highstring = high.toString * val lowstring = low.toString * * //well-formed surrogate pairs are not split * val highlow = highstring + lowstring * highlow.split(high) //returns Array(highlow) * * //bare surrogate characters are split * val bare = "_" + highstring + "_" * bare.split(high) //returns Array("_", "_") * * }}} * * @param separator the character used as a delimiter */ def split(separator: Char): Array[String] = toString.split(escape(separator))
接着回到原点,从4句代码说起,说明2处特别之处:1、为什么没有foreach,而用map(_.xxx)的方式,scala很特别,提供了占位符的方式,至于map是内部迭代的方式就不多做阐述;2、源码来自StringLike类,通过ctrl+q(idea快捷键)或者ctrl+左键查看源码不仅可以看到详细的说明,还有e.g,是不是感觉阅读起来就没那么复杂了。
二、字符串中的变量代换
书籍开篇就说到像Perl、PHP、Ruby一样,但是对于来说就是这样的感觉,根本没学过这些语言,是不是一样与我无关。但是有一点很像的是啥呢,像python、spring的SPEL,这才是我的真实感受(这是学完之后的感受),当然SPEL强大很多,毕竟不能和框架比,框架扩展的东西太多,也许你觉得学得差不多的时候,其实才摸到一点皮毛一样的感觉一样,就像spring的各种领域一样,这点可以在spring.io当中去看docs的时候感受到。
回到主题,一道开胃菜:
val name = "Fred" val age=33 val weight = 200 println(s"$name is $age years old,and weighs $weight pounds.")
学东西就从基础开始不是?这本书的架构也基本就是这样,从易到难。
打印结果可能各位已经猜出: Fred is 33 years old,and weighs 200 pounds.
字符串变量代换好像也就如此,其实还真是就是如此,并没什么特别的地方,和python很像,和SPEL很像吧!
接着来几个特殊的例子感受一下就行了,估计在实际用的时候这是个鸡肋的东西,基本用不到。
表达式计算:
Param同上,不再列出:
println(s"Age next year:${age+1}") println(s"You are 33 years old:${age==33}")
打印结果:
Age next year:34
You are 33 years old:true
对象变量:
case class Student(name:String,score:Int) val hannah = Student("Hannah",95) println(s"${hannah.name} has a score of ${hannah.score}")
接着,还来一个format的用法:
println(f"$name is $age years old,and weighs $weight%.2f pounds.")
当然这点和其他的语言一样,其实”s”和”f”都是方法,如果有需求自己就能实现,scala还支持自定义,所以个人觉得这个不是很特别的一小节。
最后,贴一下printf格式化常用符:
格式化符号 | 描述 |
%c | 字符 |
%d | 十进制数字 |
%e | 指数浮点数 |
%f | 浮点数 |
%i | 整数(十进制) |
%o | 八进制数 |
%s | 字符串 |
%u | 无符号十进制数 |
%x | 十六进制数 |
%% | 打印一个百分号 |
\% | 打印一个百分号 |