
https://github.com/timzaak/table2case 将数据库 table 转换成 case class ,并写入到文件中,额外支持 scalasql ,减少重复工作。
]]>网上下载的仓库,我的文件几乎不会改动,能不能跳过 compile ?
熟悉的大佬请指点一下,无论是能与不能。
PS:文件在这
]]>很多团队内写数据流,分为用 java 、scala 、python 三波。
鉴于目前 scala 不温不火,甚至热度有下降的趋势。
是否有必要在公司内部鼓励用 scala ?
是否有必要统一使用 java 开发,减少开发语言的技术栈的复杂度( scala 较复杂且应用不广泛)?
困扰了挺长一段时间的问题,发出来供大家讨论一下。
val pmml = new PMMLBuilder(trainingData.schema, model).build() val targetFile = "target/model.pmml" val fis: FileOutputStream = new FileOutputStream(targetFile) val fout: StreamResult = new StreamResult(fis) JAXBUtil.marshalPMML(pmml, fout) Exception in thread "main" java.lang.IllegalArgumentException: Expected string, integral, double or boolean data type, got vector data type at org.jpmml.sparkml.SparkMLEncoder.createDataField(SparkMLEncoder.java:169) at org.jpmml.sparkml.SparkMLEncoder.getFeatures(SparkMLEncoder.java:76) at org.jpmml.sparkml.feature.VectorIndexerModelConverter.encodeFeatures(VectorIndexerModelConverter.java:52) at org.jpmml.sparkml.FeatureConverter.registerFeatures(FeatureConverter.java:50) at org.jpmml.sparkml.PMMLBuilder.build(PMMLBuilder.java:114) ]]>个人的确很喜欢 scala,但它的复杂也让人望而却步,平时写 flink 和 spark 都会用 scala 写。
但是个人不喜欢太多的语法糖和特殊符号,而且 akka 的消息编程模型感觉也不容易进行抽象。
从个人职业发展角度看也想用 springboot,毕竟 springboot 还是受众比较广。
怎么搞?
]]>object test { def main(args: Array[String]): Unit = { def listTestD = (0 to 20000000).toList var l1 = System.currentTimeMillis() var sum = 0 listTestD.foreach{x=> if (x%2==0) sum = x} println(System.currentTimeMillis()-l1) sum = 0 l1 = System.currentTimeMillis() listTestD.filter(_%2==0).foreach(sum = _) println(System.currentTimeMillis()-l1) } } 执行结果是: 17585, 21059 效率差 20%左右
避免缓存,对掉两个 foreach
object test { def main(args: Array[String]): Unit = { def listTestD = (0 to 20000000).toList var l1 = System.currentTimeMillis() var sum = 0 listTestD.filter(_%2==0).foreach(sum = _) println(System.currentTimeMillis()-l1) sum = 0 l1 = System.currentTimeMillis() listTestD.foreach{x=> if (x%2==0) sum = x} println(System.currentTimeMillis()-l1) } } 执行结果是: 35082, 16201 效率差近 50%。
如果 listTestD 存储一个对象的内容,效率是不是会差更大?
]]>]]>"Combined together we hope these features will improve the user experience of running your builds."
在 Scala Logging 中:
logger.debug(s"Some $expensive message!") 会被 Scala 的宏转换成:
if (logger.isDebugEnabled) logger.debug(s"Some $expensive message!") 因为在实际代码运行时,实际上会先做字符串插值,然后在看日志级别为 DEBUG 的日志是否需要输出。所以我们通过 if 语句,防止不必要的字符串操作,进而改善性能。
在上一篇^3实现 lombok.Data 的时候,我们实际上是通过注解告诉编译器,我们需要在该注解所作用的类上面生成 getter 和 setter。说白了,就是注解 @data 让我们定位具体的类,然后我们再插入代码。而这个例子实际上是直接将生成代码的规则和具体的方法衔接起来。
完整的实现如下所示:
final class Logger private (val underlying: org.slf4j.Logger) { def debug(message: String): Unit = macro LoggerMacro.debugMessage } private object LoggerMacro { type LoggerCOntext= blackbox.Context {type PrefixType = Logger} private def deconstructInterpolatedMessage(c: LoggerContext) (message: c.Expr[String]) = { import c.universe._ message.tree match { case q"scala.StringContext.apply(..$parts).s(..$args)" => val format = parts.iterator.map({ case Literal(Constant(str: String)) => str }) // Emulate standard interpolator escaping .map(StringContext.treatEscapes) // Escape literal slf4j format anchors if the resulting call will require a format string .map(str => if (args.nonEmpty) str.replace("{}", "\{}") else str) .mkString("{}") val formatArgs = args.map(t => c.Expr[Any](t)) (c.Expr(q"$format"), formatArgs) case _ => (message, Seq.empty) } } private def formatArgs(c: LoggerContext)(args: c.Expr[Any]*) = { import c.universe._ args.map { arg => c.Expr[AnyRef]( if (arg.tree.tpe <:< weakTypeOf[AnyRef]) arg.tree else q"$arg.asInstanceOf[_root_.scala.AnyRef]" ) } } def debugMessageArgs(c: LoggerContext) (message: c.Expr[String], args: c.Expr[Any]*): c.universe.Tree = { import c.universe._ val underlying = q"${c.prefix}.underlying" val anyRefArgs = formatArgs(c)(args: _*) if (args.length == 2) q"if ($underlying.isDebugEnabled) $underlying.debug($message, _root_.scala.Array(${anyRefArgs.head}, ${anyRefArgs(1)}): _*)" else q"if ($underlying.isDebugEnabled) $underlying.debug($message, ..$anyRefArgs)" } def debugMessage(c: LoggerContext) (message: c.Expr[String]): c.universe.Tree = { val (messageFormat, args) = deconstructInterpolatedMessage(c)(message) debugMessageArgs(c)(messageFormat, args: _*) } } 首先,blackbox.Context 事实上限定了这个宏的作用域—即在类 Logger 之中。可以观察到,单例 LoggerMacro 的每一个方法都带有 LoggerContext 这个参数,每一个方法的具体实现,也和 LoggerContext 有一定的关系。
debugMessage 函数首先将字符串插值这个表达式通过 deconstructInterpolateMessage 解构成 messageFormat 和 args。下面这段代码可以非常明确的解释,什么是 messageFormat 以及什么是 args:
logger.info("Info :{}" , user.getName()) 如果是 Scala 的字符串插值的话,就是 s"Info :${user.getName}"。
解构之后,我们只需要通过 Quasiquote 将带有条件语句的代码重新构造起来就可以了。
另外一个需要注意的点是,在使用 @data 的时候,我们实际上需要在工程中开启 Paradise 插件,而我们在使用 Scala Logging 的时候,实际上直接依赖 Scala Logging 就可以了,不需要开启 Paradise 插件。这就涉及到一个问题:我们在上一节中做了详细解释的代码,到底是在哪个环节执行的。
很简单,我们可以通过在 debugMessage 增加日志的方式,确定这个细节。
最终发现,实际上,我们依赖了 Scala Logging,但是项目自身没有使用编译插件,在编译过程中,编译器遇到 Scala Logging 中会生成代码的方法时,实际上还是会去利用编译插件,生成代码。
实际上,这一篇的内容虽然在宏的具体使用接口上和 lombok.Data 那一篇有细节上的差异,但实际上最终生成代码的还是在使用 Quasiquote,所以如何高效地在 REPL 中尝试 Quasiquote 至关重要。Quasiquote 是伊甸园元编程中最枯燥最耗时的一个环节,而通过何种方式去将常规的代码和宏生成的代码衔接起来,则是伊甸园中一扇隐秘的大门。
阅读原文:Scala 元编程:在日志库中的应用
]]>class Food abstract class Animal { def eat(food: Food) } class Grass extends Food class Cow extends Animal { override def eat(food: Grass) = {} // 这不能编译 } // 如果能的话... class Fish extends Food val bessy: Animal = new Cow bessy eat (new Fish) // ...你就能给牛吃草了 本人理解 override 超类方法,方法参数是不支持协变的,但是上文假设通过编译,"bessy eat (new Fish)"不是本来就不能运行吗? Fish 本来就不能上转型为 Grass 呀。何况如下重写 eat 方法岂不是同样有这个问题?
class Cow extends Animal { override def eat(food: Food): Unit = {} } val cow = new Cow cow eat new Fish // 能通过编译且运行 小弟不才,一直没理解,希望各位大佬轻喷
]]>我想用 spark 实现检测 kafka 的数据流,如果发现 error 字样,就发送邮件。 请问各位大佬有没有相关脚本或者教程的地址可以参考的?
谢谢大家。
]]>$ sbt new scala-native/scala-native.g8 ... A minimal project that uses Scala Native. name [Scala Native Seed Project]: scala-native-playground Template applied in /path/to/scala-native-playground 只要输入你想创建的工程的名字,整个脚手架就搭建起来了。
我们试着编译运行一下这个脚手架:
$ cd scala-native-playground $ sbt sbt:scala-native-playground> compile [info] Non-compiled module 'compiler-bridge_2.11' for Scala 2.11.12. Compiling... [info] Compilation completed in 6.179s. [info] Done compiling. [success] Total time: 177 s, completed 2019-2-24 10:24:54 sbt:scala-native-playground> run [error] no clang60, clang-6.0, clang50, clang-5.0, clang40, clang-4.0, clang39, clang-3.9, clang38, clang-3.8, clang37, clang-3.7, clang found in $PATH. Install clang ( http://www.scala-native.org/en/latest/user/setup.html) [error] no clang++60, clang++-6.0, clang++50, clang++-5.0, clang++40, clang++-4.0, clang++39, clang++-3.9, clang++38, clang++-3.8, clang++37, clang++-3.7, clang++ found in $PATH. Install clang ( http://www.scala-native.org/en/latest/user/setup.html) [error] (nativeClang) no clang60, clang-6.0, clang50, clang-5.0, clang40, clang-4.0, clang39, clang-3.9, clang38, clang-3.8, clang37, clang-3.7, clang found in $PATH. Install clang ( http://www.scala-native.org/en/latest/user/setup.html) [error] (nativeClangPP) no clang++60, clang++-6.0, clang++50, clang++-5.0, clang++40, clang++-4.0, clang++39, clang++-3.9, clang++38, clang++-3.8, clang++37, clang++-3.7, clang++ found in $PATH. Install clang ( http://www.scala-native.org/en/latest/user/setup.html) [error] Total time: 0 s, completed 2019-2-24 10:26:01 能正常编译,但是运行的时候会报错。按照提示,我们需要安装一些依赖:
$ sudo apt install clang libunwind-dev 然后,在重新在 sbt 的 REPL 里面敲 Run 就可以了。大概是这样:
sbt:scala-native-playground> run [info] Linking (534 ms) [info] Discovered 800 classes and 4709 methods [info] Optimizing (debug mode) (742 ms) [info] Generating intermediate code (242 ms) [info] Produced 39 files [info] Compiling to native code (332 ms) [info] Linking native code (immix gc) (60 ms) Hello, world! [success] Total time: 3 s, completed 2019-2-24 10:27:45 整个过程还是比较流畅的,没有遇到特别浪费时间的事情,by the way,我所用的 Scala Native 版本是 0.3.8,这一点从project/plugins.sbt可以知道。
$ cat project/plugins.sbt addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.3.8") ====> 点我返回文章目录 <====
]]>import ... object DataAssign object InitAssign trait DataPrimitives[T <: Data] { // ... Other codes 其中上面这两个 object 这里都没有具体实现。请问这是什么用法,有什么参考材料么? 谢谢
]]>当时懵逼了,感觉不是默认都尽量使用 reduce by 吗,现在我能想到的情况也只有在 key 值非常少的情况下用 group by 比较好,不知道对不对。
]]>def f(s: String) = "f(" + s + ")" def g(s: String) = "g(" + s + ")" // 就是这里看不懂 val fComposeG = f _ compose g _ 想问一下 这个 _ 在这里是什么作用? 这是一种什么用法呀?
]]>t/431491。于是把它翻译成中文了,详见 Scala 中不同类型的类型。 不过有几个章节原作者还未完成。
欢迎指点和建议。
]]>参考书籍
]]>请问怎样结合项目去实践呢?或者说哪些框架(模块)适合初学者学习(阅读)呢?希望大家能谈谈自己的想法,谢谢!
]]>val list1 = List("c", "a", "l", "a") val list2 = s :: list1 // list2: (s, c, a, l, a) val list3 = List("p", "l", "a", "y") val list4 = list3 ::: list2 // list4: (p, l, a, y, s, c, a, l, a) 然后就开始吐槽:WTF,这是什么鬼? 别急,给我一分钟时间,看看能否说服你! 首先你需要了解一个基本概念,在 Scala 中一切都是方法:
"a" * 3 //等价于: "a".*(3) 2 - 1 //等价于: 2.-(1) 所以没错,你之前看到的::和:::自然也是方法,只不过是为了简洁,省略了.和()。List 是由 head 和 tail 拼接在一起的递归结构(这种设计在模式匹配时非常方便)。List 的定义可以写成如下形式:
head :: tail head 是首元素,tail 是剩余的 List。仔细瞧瞧,::看起来是不是很像胶水,将列表的头和尾紧紧地粘在一起,更进一步,:::可以把两个列表粘在一起。这样的代码是不是很简洁,并且富有表达力! 在 Scala 中,这种简洁的设计比比皆是,例如我们再来看看如何构建一个 Map 实例:
val map = Map("name" -> "PlayScala 社区", "url" -> "http://www.playscala.cn") 感受一下,是不是非常清晰明了。 当然 Scala 的魅力远不止如此,当你慢慢了解它时,你会慢慢深陷而无法自拔。 讲了那么多,我只想告诉你 Scala 并不可怕,其实在 Play Framework 中,你根本就不需要抱着 Scala 书籍啃完再写代码,PlayScala 社区会为你准备一篇 30 分钟的为 Play 初学者准备的 Scala 基础知识,读完你就可以投入 Play Framework 的怀抱了。
好了,回归正题,那为什么要创建 PlayScala 社区呢? 主要原因是国内 Play Framework 的第一手中文学习资料非常稀缺,虽然在网上可以找到一些教程,但是知识的碎片化很严重,并且很多质量较差的文章会影响初学者的认知。PlayScala 社区正是基于这样的原因而诞生的,并且希望能够实现以下几个愿景:
希望在大家的一起努力下,可以让更多的人了解并加入 Play Framework 的开发行列,不断增强 Play Framework 在国内的影响力。
]]>欢迎来访: PlayScala 社区
“如果使用 scala,可以使用如下 case class 解析出数据
case class Answer(answer_id: Long, question_id: Long, question_title: String, question_topics: Array[Long], votup_count: Long) case class Article(id: Long, title: String, votup_count: Long) case class Question(question_followers: Long, question_id: Long, question_title: String, question_topics: Array[Long]) case class userStringId(CREATED_ANSWERS: Array[Answer], CREATED_ARTICLES: Array[Article], CREATED_QUESTIONS: Array[Question], FOLLOWED_QUESTIONS: Array[Question], VOTEUPED_ANSWERS: Array[Answer], VOTEUPED_ARTICLES: Array[Article], followers_count: Long, id: String) case class userDigitalId(CREATED_ANSWERS: Array[Answer], CREATED_ARTICLES: Array[Article], CREATED_QUESTIONS: Array[Question], FOLLOWED_QUESTIONS: Array[Question], VOTEUPED_ANSWERS: Array[Answer], VOTEUPED_ARTICLES: Array[Article], followers_count: Long, id: Long) ]]>resolvers += "Hortonworks Repository" at "http://repo.hortonworks.com/content/repositories/releases/" resolvers += "Hortonworks Jetty Maven Repository" at "http://repo.hortonworks.com/content/repositories/jetty-hadoop/" 但是,如果我使用-Dsbt.override.build.repos=true 的话,这个 resolvers 就会被覆盖掉,没法使用了,有人能解决这个问题吗?感谢
]]>有朋友遇到过这个问题吗?
]]>这里有人搞过scala么?
这货上手是否要很多?里面是不是也有很多的lib要学?
额的神啊,救救我吧:(
(A,B,C) => (A,(B,C)) 这一步好说,直接取 head tail 就可以了。但是取每一个元素都做这个操作怎么搞? ]]>