# 斯卡拉高尔夫技巧

24

（这是Python中...的无耻复制）

5

## 使用ascii符号作为标识符。

``````a=>b       //ok
%=>%        //error, parsed as one token
% => %      //ok
val% =3     //ok
&contains+  //ok
if(x)&else* //ok
``````

## 使用设置代替包含

``````if (Seq(1,2,3,'A')contains x)... //wrong
if (Set(1,2,3,'A')(x))...         //right
``````

## 需要两个参数时，请使用curried函数。

``````(a,b)=>... //wrong
a=>b=>...  //right
``````

## `_`尽可能使用-syntax

``````a=>a.map(b=>b.size)) //wrong
a=>a.map(_.size)     //better
_.map(_.size)        //right
``````

## 使用部分申请

``````a=>a+1 //wrong
_+1    //better, see above
1+     //right; this treats the method + of 1 as a function
``````

## 使用`""+`代替`toString`

``````a=>a.toString //wrong
a=>a+""       //right
``````

## 使用字符串作为序列

`""` 如果您不在乎actula类型，有时是创建空序列的最短方法

## 使用BigInt在字符串之间进行数字转换

``````Integer.toString(n,b) //wrong
BigInt(n)toString b   //right
``````

``````Integer.parseInt(n,b) //wrong
BigInt(n,b)           //right
``````

## 使用Seq创建序列

``````a::b::Nil   //wrong
List(...)   //also wrong
Vector(...) //even more wrong
Seq(...)    //right
Array(...)  //also wrong, except if you need a mutable sequence
``````

``````Seq('a','z') //wrong
"az"         //right
``````

# 利用Stream无限序列

``````Stream.iterate(start)(x=>calculateNextElement(x))
``````

## 使用符号运算符而不是冗长的对应符号

`:\``:/`不是`foldRight``foldLeft`

``````a.foldLeft(z)(f) //wrong
(z/:a)(f)        //right
a.foldRight(z)(f) //wrong
(a:\z)(f)         //right
``````

`hashCode` -> `##`

`throw new Error()` -> `???`

## 别名长方法作为函数

``````def r(x:Double)=math.sqrt(x) //wrong
var r=math.sqrt _            //right; r is of type (Double=>Double)
``````

## 了解标准库中的功能

``````map
flatMap
filter
:/ and :\ (folds)
scanLeft and scanRight
sliding
grouped (only for iterators)
inits
drop and take
collect
find
zip
zipWithIndex3
distinct and/or toSet
startsWith
``````

11

``````1 to 10 map(_=>println("hi!")) // Wrong!
for(i<-1 to 10)println("hi!") // Wrong!
Seq.fill(10)(println("hi!")) // Right!
``````

10

### 可疑标识符：

``````val l=List(1,2,3)
val? =List(1,2,3)
``````

``````val ?=List(1,2,3) // illegal
``````

``````print(?size)  // l.size needs a dot
def a(? :Int*)=(?,?tail).zipped.map(_-_)
``````

``````       print(?size)
3
print(?size-5)
<console>:12: error: Int does not take parameters
print(?size-5)
^
``````

9

## 馆藏

``````val l=List(1,2,3)
val s=Seq(1,2,3)
``````

``````val s=Seq(1,2,3)
val t=(1,2,3)
``````

``````s(0)
t._1
``````

``````scala> s.map(_*2)
res55: Seq[Int] = List(2, 4, 6)

scala> t.map(_*2)
<console>:9: error: value map is not a member of (Int, Int, Int)
t.map(_*2)
^
``````

### 更新

``````def foo(s:Seq[Int])
def foo(s:Int*)
``````

8

``````List("a","b","c") foreach println
``````

``````List("a","b","c") map println
``````

7

``````def f(a:String,b:String,c:String)
``````

``````type S=String;def f(a:S,b:S,c:S)
``````

``````val a=Array(Array(1,2),Array(3,4))
``````

``````val A=Array;val a=A(A(1,2),A(3,4))
``````

`#define`例如，这也适用于C ++ ，但我承认这样做很好，`def`而且`val`更短。

`def`是定义方法的关键字，对c ++的简单翻译`val`是'const'，它是一个声明，但是通常会推断出类型。在第一种情况下，起酥油`type=`更接近`typedef`-是吗？第二个例子不是我的，对我来说是新的。我必须提防，在哪里使用它。

`typedef long long ll;`与相同`#define ll long long`，因此后者要短1。但是，`typedef`确实可以。`val`再次看这个例子，我肯定会误读它。似乎与Scala无关。 `x = thingWithAReallyLongComplicatedNameForNoReason`是一个相当普遍的策略：P

@userunknown当使用语法实例化`List`or `Array`等时，`val x = List(1,2,3)`您只是`apply``List`对象上调用方法。（与使用`new`。构造函数相反，这种创建对象的技术被称为“工厂方法” 。）因此，在上面，我们只是制作了一个新变量，该变量指向与变量名相同的单例对象`Array`。由于是同一件事，因此所有方法（包括`apply`）都可用。

7

``````List(1,2,3,4).filter(_ % 2 == 0) // change to:
List(1,2,3,4)filter(_%2==0)
``````

7

`true``false`文字更短，以写为`2>1`真正的和`1>2`虚假的

7

``````val n,k=readInt
``````

（在其他地方看到过，但现在找不到）。

6

`````` x.replaceAll(y,z)

type S=String; def r(x:S,y:S,z:S)=x.replaceAll(y,z)
``````

3

``````var(a,b,c)=("One","Two","Three") //32 characters
``````

``````var a="One";var b="Two";var c="Three" //37 characters
``````

0

1