scala在线编译器(scala官网中文教程)

http://www.itjxue.com  2023-02-24 03:59  来源:未知  点击次数: 

Spark Shell因为Scala编译器原因不能正常启动怎么解决

Spark Shell由于Scala编译器原因不能正常启动

使用SBT安装完成Spark后,可以运行示例,但是尝试运行spark-shell就会报错:

D:\Scala\spark\bin\spark-shell.cmd

SLF4J: Class path contains multiple SLF4J bindings.

SLF4J:

Found binding in

[jar:file:/D:/Scala/spark/assembly/target/scala-2.10/spark-assembly-0.9.0-incubating-hadoop1.0.4.jar!/org/slf4j/impl/StaticLoggerBinder.class]

SLF4J: Found binding in

[jar:file:/D:/Scala/spark/tools/target/scala-2.10/spark-tools-assembly-0.9.0-incubating.jar!/org/slf4j/impl/StaticLoggerBinder.class]

SLF4J: See for an explanation.

SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]

14/04/03 20:40:43 INFO HttpServer: Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties

14/04/03 20:40:43 INFO HttpServer: Starting HTTP Server

Failed to initialize compiler: object scala.runtime in compiler mirror not found.

** Note that as of 2.8 scala does not assume use of the java classpath.

** For the old behavior pass -usejavacp to scala, or if using a Settings

** object programatically, settings.usejavacp.value = true.

14/04/03

20:40:44 WARN SparkILoop$SparkILoopInterpreter: Warning: compiler

accessed before init set up.? Assuming no postInit code.

Failed to initialize compiler: object scala.runtime in compiler mirror not found.

** Note that as of 2.8 scala does not assume use of the java classpath.

** For the old behavior pass -usejavacp to scala, or if using a Settings

** object programatically, settings.usejavacp.value = true.

Failed to initialize compiler: object scala.runtime in compiler mirror not found.

??????? at scala.Predef$.assert(Predef.scala:179)

???????

at

org.apache.spark.repl.SparkIMain.initializeSynchronous(SparkIMain.scala:197)

???????

at

org.apache.spark.repl.SparkILoop$$anonfun$process$1.apply$mcZ$sp(SparkILoop.scala:919)

???????

at

org.apache.spark.repl.SparkILoop$$anonfun$process$1.apply(SparkILoop.scala:876)

???????

at

org.apache.spark.repl.SparkILoop$$anonfun$process$1.apply(SparkILoop.scala:876)

???????

at

scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135)

???????

at org.apache.spark.repl.SparkILoop.process(SparkILoop.scala:876)

???????

at org.apache.spark.repl.SparkILoop.process(SparkILoop.scala:968)

??????? at org.apache.spark.repl.Main$.main(Main.scala:31)

??????? at org.apache.spark.repl.Main.main(Main.scala)

Google

之还是不求解。只是在SBT的网站上看到QA里面有个问题提到了:

/docs/faq#how-do-i-use-the-scala-interpreter-in-my-code。这里说代码中怎么修改设置。显然不

适合我。

继续求解。注意到错误提示是在2.8以后才有的,原因是有一个关于编译器解释权Classpath的提议被接受了:Default compiler/interpreter classpath in a managed environment。

继续在Google中找,有一篇论文吸引了我的注意:Object Scala Found。里面终于找到一个办法:

However, a working command can be recovered, like so:

$ jrunscript -Djava.class.path=scala-library.jar -Dscala.usejavacp=true -classpath scala-compiler.jar -l scala

于是修改一下\bin\spark-class2.cmd:

rem Set JAVA_OPTS to be able to load native libraries and to set heap size

set

JAVA_OPTS=%OUR_JAVA_OPTS% -Djava.library.path=%SPARK_LIBRARY_PATH%

-Dscala.usejavacp=true -Xms%SPARK_MEM% -Xmx%SPARK_MEM%

rem Attention: when changing the way the JAVA_OPTS are assembled, the change must be reflected in ExecutorRunner.scala!

标红的部分即是心添加的一个参数。再次运行\bin\spark-shell.cmd:

D:D:\Scala\spark\bin\spark-shell.cmd

SLF4J: Class path contains multiple SLF4J bindings.

SLF4J:

Found binding in

[jar:file:/D:/Scala/spark/assembly/target/scala-2.10/spark-assembly-0.9.0-incubating-hadoop1.0.4.jar!/org/slf4j/impl/StaticLoggerBinder.class]

SLF4J: Found binding in

[jar:file:/D:/Scala/spark/tools/target/scala-2.10/spark-tools-assembly-0.9.0-incubating.jar!/org/slf4j/impl/StaticLoggerBinder.class]

SLF4J: See for an explanation.

SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]

14/04/03 22:18:41 INFO HttpServer: Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties

14/04/03 22:18:41 INFO HttpServer: Starting HTTP Server

Welcome to

?????

____?????????????

__

???? / __/__? ___ _____/ /__

??? _\ \/ _ \/ _ `/ __/? '_/

?? /___/ .__/\_,_/_/ /_/\_\?? version 0.9.0

????? /_/

Using Scala version 2.10.3 (Java HotSpot(TM) Client VM, Java 1.6.0_10)

Type in expressions to have them evaluated.

Type :help for more information.

14/04/03 22:19:12 INFO Slf4jLogger: Slf4jLogger started

14/04/03 22:19:13 INFO Remoting: Starting remoting

14/04/03 22:19:16 INFO Remoting: Remoting started; listening on addresses :[akka.tcp://spark@Choco-PC:5960]

14/04/03 22:19:16 INFO Remoting: Remoting now listens on addresses: [akka.tcp://spark@Choco-PC:5960]

14/04/03 22:19:16 INFO SparkEnv: Registering BlockManagerMaster

14/04/03

22:19:17 INFO DiskBlockManager: Created local directory at

C:\Users\Choco\AppData\Local\Temp\spark-local-20140403221917-7172

14/04/03 22:19:17 INFO MemoryStore: MemoryStore started with capacity 304.8 MB.

14/04/03 22:19:18 INFO ConnectionManager: Bound socket to port 5963 with id = ConnectionManagerId(Choco-PC,5963)

14/04/03 22:19:18 INFO BlockManagerMaster: Trying to register BlockManager

14/04/03 22:19:18 INFO BlockManagerMasterActor$BlockManagerInfo: Registering block manager Choco-PC:5963 with 304.8 MB RAM

14/04/03 22:19:18 INFO BlockManagerMaster: Registered BlockManager

14/04/03 22:19:18 INFO HttpServer: Starting HTTP Server

14/04/03 22:19:18 INFO HttpBroadcast: Broadcast server started at

14/04/03 22:19:18 INFO SparkEnv: Registering MapOutputTracker

14/04/03

22:19:18 INFO HttpFileServer: HTTP File server directory is

C:\Users\Choco\AppData\Local\Temp\spark-e122cfe9-2d62-4a47-920c-96b54e4658f6

14/04/03 22:19:18 INFO HttpServer: Starting HTTP Server

14/04/03 22:19:22 INFO SparkUI: Started Spark Web UI at

14/04/03 22:19:22 INFO Executor: Using REPL class URI:

Created spark context..

Spark context available as sc.

scala :quit

Stopping spark context.

14/04/03 23:05:21 INFO MapOutputTrackerMasterActor: MapOutputTrackerActor stopped!

14/04/03 23:05:21 INFO ConnectionManager: Selector thread was interrupted!

14/04/03 23:05:21 INFO ConnectionManager: ConnectionManager stopped

14/04/03 23:05:21 INFO MemoryStore: MemoryStore cleared

14/04/03 23:05:21 INFO BlockManager: BlockManager stopped

14/04/03 23:05:21 INFO BlockManagerMasterActor: Stopping BlockManagerMaster

14/04/03 23:05:21 INFO BlockManagerMaster: BlockManagerMaster stopped

14/04/03 23:05:21 INFO SparkContext: Successfully stopped SparkContext

14/04/03 23:05:21 INFO RemoteActorRefProvider$RemotingTerminator: Shutting down remote daemon.

14/04/03

23:05:21 INFO RemoteActorRefProvider$RemotingTerminator: Remote daemon

shut down; proceeding with flushing remote transports.

Good。浏览器打开,就可以看到Spark的状态、环境、执行者等信息了。

这个Fix可能只是适用与我的情况。如果还有问题可以再找找相关的资料。

期间还碰到不能找到文件的错误。最后发现是JAVA_HOME设置没有对。如果你碰到问题了,可以打开脚本的回显,然后找找原因。

Scala型变

「型变(Variance)」是一个令人费解的概念,但它却是理解类型系统的重要基石。本文首先讨论型变的基本概念,深入理解型变的基本形态。然后以 List, Option 为例讲解型变在 Scala 中的应用;最后通过 ScalaHamcrest 的实战,加深对此概念的理解和运用。

其中, Mutable 常常意味着 Nonvariant ,但是 Noncovariant 与 Mutable 分别表示两个不同的范畴。

「型变(Variance)」拥有三种基本形态:协变(Covariant), 逆变(Contravariant), 不变(Nonconviant),可以形式化地描述为:

Scala 的类型参数使用 + 标识「协变」, - 标识「逆变」,而不带任何标识的表示「不变」(Nonvariable)。

事实上,判定一个类型是否拥有型变能力的准则非常简单。

Supplier 是一个生成者,它生产 T 类型的实例。

Consumer 是一个消费者,它消费 T 类型的实例。

Function1 是一个一元函数,它既是一个生产者,又是一个消费者,但它是不可变的(Immutable)。其中,入参类型为 -T ,返回值类型为 +R ;对于参数类型,函数是逆变的,而对于返回值类型,函数则是协变的。

与 Function1 不同,虽然数组类型既是一个生产者,又是一个消费者。但是,它是一个可变的(Mutable)类型,因此它是不变的(Nonvariant)。

综上述,可以得到 2 个简单的结论。

幸运的是, Scala 编译器能够完成这个约束的检查。例如,

编译器将检测到编译错误。

例如,给定两个函数 F1, F2 。

则 F1 : F2 成立。

Option 是一个递归的数据结构,它要么是 Some ,要么是 None 。其中, None 表示为空,是递归结束的标识。

使用 Scala ,可以很直观地完成 Option 的递归定义。

因为 Option 是不可变的(Immutable),因此 Option 应该设计为协变的,即 Option[+A] 。也就是说,对于任意的类型 A , Option[Nothing] : Option[A] ,即 None : Option[A] 都成立。

与 Option 类似, List 也是一个递归的数据结构,它由头部和尾部组成。其中, Nil 表示为空,是递归结束的标识。

使用 Scala ,可以很直观地完成 List 的递归定义。

因为 List 是不可变的(Immutable),因此 List 应该设计为协变的,即 List[+A] 。也就是说,对于任意的类型 A , List[Nothing] : List[A] ,即 Nil : List[A] 都成立。

可以在 List 中定义了 cons 算子,用于在 List 头部追求元素。

此时,编译器将报告协变类型 A 出现在逆变的位置上的错误。因此,在遵循「里氏替换」的基本原则,使用「下界(Lower Bound)」对 A 进行界定,转变为「不变的(Nonvariable)」的类型参数 A1 。

至此,又可以得到一个重要的结论。

List 的 cons 算子就是通过使用「下界」界定协变类型参数 A ,将其转变为不变的(Nonvariable)类型参数 A1 的。而对于「上界」,通过实现 ScalaHamcrest 的基本功能进行讲述,并完成整个型变理论知识的回顾和应用。

对于任意的类型 A , A = Boolean 常常称为「谓词」;如果该谓词用于匹配类型 A 的某个值,也常常称该谓词为「匹配器」。

ScalaHamcrest 首先定义一个 Matcher ,并添加了 , ||, ! 的基本操作,用于模拟谓词的基本功能。

对于函数 A = Boolean ,类型参数 A 是逆变的。因此,为了得到支持型变能力的 Matcher ,应该将类型参数 A 声明为逆变。

但是,此时 , || 将报告逆变类型 A 出现在协变的位置上。为此,可以使用「上界」对 A 进行界定,转变为不变的(Nonvariant)类型 A1 。

基于 Matcher ,可以定义特定的原子匹配器。例如:

也可以定义 EqualTo 的原子匹配器,用于比较对象间的相等性。

与 EqualTo 类似,可以定义原子匹配器 Same ,用于比较对象间的一致性。

其中, A : AnyRef类型 对 A 进行界定,排除 AnyVal 的子类误操作 Same 。类似于类型上界,也可以使用其他的类型界定形式;例如,可以定义 InstanceOf ,对类型 A 进行上下文界定,用于匹配某个实例的类型。

有时候,基于既有的原子可以很方便地构造出新的原子。

也可以将各个原子或者组合器进行组装,形成威力更为强大的组合器。

特殊地,基于 AnyOf/AllOf ,可以构造很多特定的匹配器。

修饰也是一种特殊的组合行为,用于完成既有功能的增强和补充。

其中, Not, Is 是两个普遍的修饰器,可以修饰任意的匹配器;也可以定义针对特定类型的修饰器。例如,可以定义针对字符串操作的原子匹配器和修饰匹配器。

如果要忽略大小写,则可以通过定义 IgnoringCase ,修饰既有的字符串的原子匹配器。

有时候,可以通过定义语法糖,提升用户感受。例如,可以使用 Not 替换 Not(EqualTo) , Is 替代 Is(EqualTo) ,不仅减轻用户的负担,而且还能提高表达力。

至此,还不知道 ScalaHamcrest 如何使用呢?可以定义一个实用方法 assertThat 。

其中, assert 定义于 Predef 之中。例如存在如下一个测试用例。

也可以使用 直接连接多个匹配器形成调用链,替代 AllOf 匹配器。

此处为了演示「型变」的作用, ScalaHamcrest 采用了 OO 与 FP 相结合的设计手法,在下一章讲解「Scala函数论」时, ScalaHamcrest 将采用纯函数式的设计手法实现,敬请关注。

scala ide是干什么用的

Scala是一门现代的多范式编程语言,志在以简练、优雅及类型安全的方式来表达常用编程模式。它平滑地集成了面向对象和函数语言的特性。

Scala是面向对象的:Scala是一个纯面向对象语言,在某种意义上来讲所有数值都是对象。对象的类型和行为是由class和trait来描述的。Class的抽象可由子类化和一种灵活的基于mixin的组合机制(它可作为多重继承的简单替代方案)来扩展。

Scala是函数式的: Scala还是一个函数式语言,在某种意义上来讲所有函数都是数值。Scala为定义匿名函数提供了一种轻量级的语法,它支持高阶(higher-order)函数、允许函数嵌套、支持局部套用(currying)。Scala的case类及其内置支持的模式匹配模型代数类型在许多函数式编程语言中都被使用。

Scala是静态类型的:Scala配备了一套富有表现力的类型系统,该抽象概念以一种安全的和一致的方式被使用。

Scala是可扩展的:Scala的设计承认了实践事实,领域特定应用开发通常需要领域特定语言扩展。Scala提供了一个独特的语言组合机制,这可以更加容易地以类库的形式增加新的语言结构:两者结合使用可方便地定义新语句,无需扩展语法,也无需使用类似宏的元编程工具。

任何方式可以被用作中缀(infix)或后缀(postfix)操作符

闭包按照所期望的类型(目标类型)自动地被构造

Scala可与Java和.NET进行互操作:Scala设计时就考虑了与流行编程环境良好交互,如Java 2运行时环境(JRE)和 .NET框架(CLR)。特别是与主流面向对象语言,如Java和C#尽量无缝交互。Scala有像Java和C#一样的编译模型(独立编译,动态装载类),允许访问成千上万的高质量类库。

对于某些开发者来说,这些刺激已足以引诱他们脱离Java进入Scala世界。但对另外一些开发者来说,它们并没有为Java世界里当前正在演绎的日复一日的编程活动提供更多好处。

在一篇名为“Scala:集Ruby和Java之所长”的博文中,Ian讲述了或许不应在Java和Scala之间做出选择,相反,相对于选择其它语言如Ruby,选择使用Java和Scala的混合物是的另一种选择:

许多开发者热爱Ruby,不过他们不能从中获取足够的东西。它可能是最具侵略性的语言之一,因为Java才是第一个到场的。人们总是引证Ruby的灵活而可扩展的语法、闭包等特性,以及其代码如何简明和具有表现力。

例如,你可以用一个简单语法创建一个Map(Ruby称之为“hashes”,尽管hashtable只是map一种可能的实现方式),如:

numberMap = {"one" = 1, "two" = 2, "three" = 3}

Java与之对等的语句显得颇为冗长:

MapString, Integer numberMap = new HashMapString, Integer(); numberMap.put("one", 1); numberMap.put("two", 2); numberMap.put("three", 3);

那么Scala怎么样呢?让我们看看Scala中map的例子:

var numberMap = Map("one" - 1, "two" - 2, "three" - 3)

你会注意到它看上去非常类似等价的Ruby代码,但是这儿有一些重要区别。特别是,就像Java,Scala编译器知道numberMap使用String作为键,Integer作为值。与Java不同的是,你无需告知,它本身就能领会这一点!这称为“类型推理(type inference)”。

这意味着如果你试图给numberMap增加一个新的键值对,但是要使用Integer作为键,String作为值,Scala将在你试图编译它时立刻报错(或者你的IDE将立刻警告你)。使用Ruby,只有当你运行你的软件并试图从该Map中找回该键和值时,得到的分别是Integer和String而不是所期望的String和Integer,这时才会导致报错。

过分强调编译时类型检查节省多少多少时间是困难的,但它消除了所有类在执行时将会产生的bug。Scala给你带来了这一好处,而且代码并不繁琐。

为更进一步在一个小例子中展现代码量的缩减,Ted Neward研究了开发同一个类,用Java、C#、Virual Basic、Ruby和Scala的区别。请参考其博文Scala pt 2:简短。

Ian继续指出:

Scala还有一连串其它好的Ruby特性(Java所缺乏的),包括闭包,以及非常适合“领域特定语言”的可塑性语法。它拥有所有这些特性,而且结合了静态类型好处。

David MacIver在其博文说正经的,为什么选择Scala?中分享了他对于面向对象编程、面向模块编程、静态类型、函数编程以及该语言中他所喜欢的未言明特性的观点。他补充道:

Scala离完美还差得远。它有一些语法缺陷,一些由Java带来的问题,一个有适度问题的编译器以及一堆你记不住的琐碎特性和边界情况(edge case)。然而,我发现这些问题除了烦你之外并不真正产生什么后果。如果只是想坐下来书写好的代码,该语言的核心是强大的和非常有用的。

为了提供一个均衡的观点,David在其博文中接着探讨了为什么不选Scala,文中他阐述了一些边界情况(edge case)。作为总结,David有如下评论:

总而言之,我发现这些只是增加了一些烦心事。它仍是我最喜欢的JVM语言,但是你的看法将取决于你怎样搁置那些对你来说可能是更重要的需要优先考虑的事情。

为了展现Scala是一门不断成熟的语言,Programming in Scala一书很快将会出版。如果等不及,Artima网站上有该书PDF格式的预印版。

Scala编程语言简介

Scala编程语言近来抓住了很多开发者的眼球 如果你粗略浏览Scala的网站 你会觉得Scala是一种纯粹的面向对象编程语言 而又无缝地结合了命令式和函数式的编程风格 Christopher Diggins认为

不太久之前编程语言还可以毫无疑义地归类成 命令式 或者 函数式 Scala代表了一个新的语言品种 它抹平了这些人为划分的界限

根据David Rupp在博客中的说法 Scala可能是下下一代Java 这么高的评价让人不禁想看看它到底是什么东西

Scala有几项关键特性表明了它的面向对象的本质 例如 Scala中的每个值都是一个对象 包括基本数据类型(即布尔值 数字等)在内 连函数也是对象 另外 类可以被子类化 而且Scala还提供了基于mixin的组合(mixin based position)

与只支持单继承的语言相比 Scala具有更广泛意义上的类重用 Scala允许定义新类的时候重用 一个类中新增的成员定义(即相较于其父类的差异之处) Scala称之为mixin类组合

Scala还包含了若干函数式语言的关键概念 包括高阶函数(Higher Order Function) 局部套用(Currying) 嵌套函数(Nested Function) 序列解读(Sequence Comprehensions)等等

Scala是静态类型的 这就允许它提供泛型类 内部类 甚至多态方法(Polymorphic Method) 另外值得一提的是 Scala被特意设计成能够与Java和 NET互操作 Scala当前版本还不能在 NET上运行(虽然上一版可以) 但按照计划将来可以在 NET上运行

Scala可以与Java互操作 它用scalac这个编译器把源文件编译成Java的class文件(即在JVM上运行的字节码) 你可以从Scala中调用所有的Java类库 也同样可以从Java应用程序中调用Scala的代码 用David Rupp的话来说

它也可以访问现存的数之不尽的Java类库 这让(潜在地)迁移到Scala更加容易

这让Scala得以使用为Java 或者 编写的巨量的Java类库和框架 Scala会经常性地针对这几个版本的Java进行测试 Scala可能也可以在更早版本的Java上运行 但没有经过正式的测试 Scala以BSD许可发布 并且数年前就已经被认为相当稳定了

说了这么多 我们还没有回答一个问题 为什么我要使用Scala? Scala的设计始终贯穿着一个理念

创造一种更好地支持组件的语言 (《The Scala Programming Language》 Donna Malayeri)

也就是说软件应该由可重用的部件构造而成 Scala旨在提供一种编程语言 能够统一和一般化分别来自面向对象和函数式两种不同风格的关键概念

藉著这个目标与设计 Scala得以提供一些出众的特性 包括

* 面向对象风格

* 函数式风格

* 更高层的并发模型

Scala把Erlang风格的基于actor的并发带进了JVM 开发者现在可以利用Scala的actor模型在JVM上设计具伸缩性的并发应用程序 它会自动获得多核心处理器带来的优势 而不必依照复杂的Java线程模型来编写程序

* 轻量级的函数语法

o 高阶

o 嵌套

o 局部套用(Currying)

o 匿名

* 与XML集成

o 可在Scala程序中直接书写XML

o 可将XML转换成Scala类

* 与Java无缝地互操作

Scala的风格和特性已经吸引了大量的开发者 比如Debasish Ghosh就觉得

我已经把玩了Scala好一阵子 可以说我绝对享受这个语言的创新之处

lishixinzhi/Article/program/Java/hx/201311/26873

Scala在线安装后eclipse上怎么没有

一、Scala 安装(windows)

可以从 Scala 主页: 下载 Scala 包,截止到目前为止,最新的发行版是 2.7.6-final

下载完成后解压,比如解压目录是d:/Program Files/scala-2.7.6,然后将d:/Program Files/scala-2.7.6/bin加如到环境变量path中

在cmd输入scala -version查看是否安装成功

二、开发环境(这里选eclipse+scala_eclipse_plugin)

这里需要注意的是,scala的eclipse插件是eclipse 3.5的

插件也支持3.4,但是需要手动下载插件安装包

如果在3.5eclipse中无法安装,就先更新eclipse到最新,然后安装

Eclipse的Scala的插件下载地址为:,也可以通过Eclipse 的Update Manager 的方式下载:

三、scala简单示例开发

1.打开window--open perspective--other--scala

2.file--new--Scala project 输入项目名称。。。路径。。。

3.在生成的项目中建立一个scala的文件,假定为HelloWorld

在HelloWorld中增加代码

object HelloWorld {

def main(args: Array[String]) {

println("HelloWorld");

}

}

然后run as--scala Application

即可看到scala的输出:HelloWorld

idea怎么在线安装scala并且启动'

下载与配置IDEA

里面有Ultimate(最终版)和Community(社区版),对于普通的开发者来说,社区版就够了,然后因为我本来配置了JDK所以就下载无JDK版本的了。?

下载好了找个合适的地方解压,之后要配置一下

sudo gedit /etc/profile1

之后添加

export IDEA_JDK=/usr/java/jdk1.8.0_1211

否则IDEA找不到JDK可别怪我?

这样你就能成功打开IDEA了

//进入idea安装目录下运行fish@fish-computer:~/workspace/idea/bin$ ./idea.sh12

你的第一个scala程序

首先要安装scala组件,File-Setting-Plugins-scala 然后安装就可以了(就是那里Uninstall,没安装的话应该是Install)?

然后new 一个project,选择sbt?

进去之后命名什么的,然后第一次进底下会配置好多乱七八糟的东西,你需要等一会(我等了五六分钟吧)?

然后在这个目录下右键new一个scala class?

然后ctrl+j快捷创建main函数和prinln

object HelloWorld { ?def main(args: Array[String]): Unit = {

? ?println("hello world")

?}

}123456

然后直接run起来就可以啦?

阅读全文

(责任编辑:IT教学网)

更多

推荐淘宝营销文章