scala for循环跳出
1 嵌套函数
object TestClient extends App {
var res =0;
def forOuter={
def forInner {
for(i<- 0 until 10 ){
if (i==5){return}
res += i
}
}
forInner
res
}
forOuter
print(res)
}
嵌套函数,就是外面包一层,然后里面有函数定义其中函数的定义是自己调用自己,也有函数的调用。也就是函数的递归调用需要我们去包装一层。而不是直接调用。
注意 forInner 后面没有=号,表示没有返回值,有等号表示有返回值,加了=号,return会报错
2 高级for循环 ,if守卫,这里其实是循环终止有两个条件判断,一个是i<10,一个是flag=true
object TestClient extends App {
var flag = true
var res = 0
for (i <- 0 until 10 if flag) {
res += i
if (i == 4) flag = false
}
println(res)
}
可以用变量<- 表达式 提供多个生成器,分号隔开,每个生成器都可以带一个守卫。比如
for (i<- 1 to 3 ;j<- 1to 3 if i!=j )
使用breakable代码块
3、使用Breaks类的break方法
跟java里面的break比较类似,相对来说,比较灵活好用;与breakable代码块配合使用
import scala.util.control.Breaks._
var res = 0
breakable {
for (i <- 0 until 10) {
if (i == 5) {
break;
}
res += i
}
}
for 推导式
for (i<- 0to 10 ) yield i*2
抽象出来就是for list yield x的expression
object TestClient extends App {
lazy val words = scala.io.Source.fromFile("D:\\maven-settings-public.xml").mkString
println(words)
}
数组和数组缓冲
import scala.collection.mutable.Buffer
import scala.collection.mutable.ArrayBuffer
import scala.collection.JavaConversions.bufferAsJavaList
object TestClient extends App {
val b = new ArrayBuffer[Int]
b +=1 //末尾添加元素
b += (2,3,4) //添加集合,用括号括起来
b ++= Array(12,-1,5) //++=添加任何集合
b.insert(2,6)
b.remove(2)
b.insert(3,-5)
b.insert(4,-12)
var first =true
//拿到正数和第一个负数,其他去掉
val indexes = for(i<-0 until b.length if first||b(i)>0) yield {if(b(i)<0) first=false;i}
for(j<-0 until indexes.length) b(j) = b(indexes(j))
b.trimEnd(b.length-indexes.length)
for(item<- b) println(item)
//java 和scala互相转化 就是两套系统的相互转化
//ArrayBuffer===>List(java的方法需要入参是List,直接把ArrayBuffer转成List)
val command = ArrayBuffer("ls","-al","/home/ssy")
val pb = new ProcessBuilder(command)
//当java的返回值是List,scala需要转化换成ArrayBuffer
import scala.collection.JavaConversions.asScalaBuffer
val cmd:Buffer[String] = pb.command()
}
类
class Person{
var age=0
def increment()={age+=1}
def current()={age}
}
class Person{
private var age=0
def increment()={age+=1}
def current()={age}
}
class Person{
protected var age=0
def increment()={age+=1}
def current()={age}
}
分别编译之后
scalac Person.scala
javap -private Person.class
public class Person { //public (default)
private int age;
public int age();
public void age_$eq(int);
public void increment();
public int current();
public Person();
}
public class Person { //private
private int age;
private int age();
private void age_$eq(int);
public void increment();
public int current();
public Person();
}
public class Person { //protected
private int age;
public int age();
public void age_$eq(int);
public void increment();
public int current();
public Person();
}
//当age是val变量时
public class Person {
private final int age;
public int age();
public int current();
public Person();
}
可以发现,不论变量到底是private,protected ,public 都会有private的变量。如果是protected和public就会有public的get/set方法 age和age_=,这里的下划线,理解成占位符。有一些东西,但是不知道是什么
如果age变量是val的话,那就是只有get方法了,因为val不可变。
如果不需要get/set方法,就生明为private[this](只能自己对象访问自己对象,即使同一个类的对象也不行,但是外部类的变量可以访问)
scala中的变量,包括属性和get/set方法
如果需要java版本的get/set方法。
import scala.beans.BeanProperty
class Person{
@BeanProperty var age = 0
def current()={age}
}
编译之后:
public class Person {
private int age;
public int age();
public void age_$eq(int);
public int current();
public int getAge();
public void setAge(int);
public Person();
}
主构造器就是把类的定义也看做是函数的定义。糅合在一起。
辅助构造器名称是this。每个辅助构造器,要先调用主构造器或者前面定义过的辅助构造器。
构造器虽然也可以看做是函数的定义,但是有个特点,就是方法签名后面不跟=号,而是直接跟方法体
class Person{
private var name = ""
private var age = 0
def this(name:String) {
this()
this.name = name
}
def this(name:String,age:Int){
this(name)
this.age =age
}
}
嵌套类以及类型投影
scala有一种类型叫路径依赖类型
,比如外部类Outer,内部类Inner。
inner1 = new outer1.InnerClass
和java不同的是,java只认类型,类型和具体实例无关。
那问题来了,怎么让外部类的方法,接受另外一个实例的内部类作为方法参数呢。
答案就是用类型投影
。
class Outter{
public class Inner {}
public void foo(Inner c){
System.out.println(c);
}
}
public class Main {
public static void main(String[] args)throws Exception{
Outter o1 = new Outter();
Outter o2 = new Outter();
Outter.Inner i1 = o1.new Inner();
Outter.Inner i2 = o2.new Inner();
o1.foo(i2);
}
}
创建Inner实例,只是和Outer.Inner i1 = o1.new Inner();
object TypeProjection extends App{
val outter1 = new OutterClass
outter1.getName("电脑")
val inner1 = new outter1.InnerClass
inner1.getName("主机")
println(outter1)
val outter2 = new OutterClass
outter2.getName("洗衣机")
val inner2 = new outter2.InnerClass
inner2.getName("滚筒")
println(outter2)
println("==============无类型投影=================")
//如果我想把洗衣机的滚筒这个内部类放到电脑这里的getInner方法里
outter1.getInner(inner1)//放自己的没问题,也没意义的样子
//outter1.getInner(inner2)
println("==============类型投影=================")
outter1.getInner2(inner2)//新添加一个类型投影就可以了
}
/**
* 外部类,内部类其实是外部类的一个成员,不像JAVA一样
*/
class OutterClass{
outter =>
var name: String = _
def getName(getname: String): Unit ={
this.name = getname
}
def getInner(innerClass: InnerClass) = {
println("innerClass'name is " + innerClass.name)//调用内部类成员
println("I'm a " + name + "!!!I'm aloof")
}
def getInner2(innerClass: OutterClass#InnerClass) = {
println("innerClass'name is" + innerClass.name)//调用内部类成员
println("I'm a " + name + " !!!I'm aloof")
}
/**
* 内部类
*/
class InnerClass{
inner =>
var name: String = _
def getName(getname: String): Unit ={
this.name = getname
}
def say: Unit ={
println("outterClass is " + outter.name)//调用外部类成员
print("I'm a Innerclass!!!I'm proud")
}
}
}
在scala里,内部类型(排除定义在object内部的),想要表达所有的外部类A实例路径下的B类型,即对 a1.B 和 a2.B及所有的 an.B类型找一个共同的父类型,这就是类型投影,用 A#B的形式表示。
对象object
object Accounts {
private var lastNumber = 0
/**
* 定义一个getNumber的方法
*
* @return
*/
def getNumber(): Int = {
lastNumber += 1
lastNumber
}
def main(args: Array[String]): Unit = {
// 相当于java静态方法调用
println(Accounts.getNumber())
}
编译之后,生成两个class文件一个是Account.class一个是Account$.class
public final class Accounts {
public static void main(java.lang.String[]);
public static int getNumber();
}
public final class Accounts$ {
public static Accounts$ MODULE$;
private int lastNumber;
public static {};
private int lastNumber();
private void lastNumber_$eq(int);
public int getNumber();
public void main(java.lang.String[]);
private Accounts$();
}
我们发现Accounts$是一个单例模式的,构造器私有化。然后Accounts 里面都是静态的方法。所以我们静态调用访问的应该是这个类。而且两个都是final类。
我们再加上伴生对象试试
object Account{
//可以互相访问私有变量指的是可以点出来,前提是有对象
def print(a:Account):Unit={println(a.lastNumber)}
}
class Account {
private var lastNumber = 0
/**
* 定义一个getNumber的方法
*
* @return
*/
def getNumber(): Int = {
lastNumber += 1
lastNumber
}
def main(args: Array[String]): Unit = {
// 相当于java静态方法调用
val number = new Account().getNumber()
println(lastNumber)
}
}
编译之后,两个class文件
public class Account {
private int Account$$lastNumber;
public static void print(Account);
public int Account$$lastNumber();
private void Account$$lastNumber_$eq(int);
public int getNumber();
public void main(java.lang.String[]);
public Account();
}
public final class Account$ {
public static Account$ MODULE$;
public static {};
public void print(Account);
private Account$();
}
辅助构造器
1 名称是this. 而且必须以主构造器的调用或者用已经定义的辅助构造器调用为先。
主构造器的参数会被编译成字段。
class Constructor2 {
println("just a tip")
}
object Test3 {
def main(args: Array[String]): Unit = {
val cons = new Constructor2();
}
}
//输出just a tip
主构造器会定义了构造器中的所有语句。
网友评论