我正在为现有的Java库编写一组隐式Scala包装类(这样我就可以装饰该库以使Scala开发人员更方便).
作为一个简单的例子,让我们说Java库(我无法修改)有一个类,如下所示:
public class Value<T> {
// Etc.
public void setValue(T newValue) {...}
public T getValue() {...}
}
Run Code Online (Sandbox Code Playgroud)
现在让我们说我想用Scala风格的getter和setter 来装饰这个类.我可以使用以下隐式类来完成此操作:
final implicit class RichValue[T](private val v: Value[T])
extends AnyVal {
// Etc.
def value: T = v.getValue
def value_=(newValue: T): Unit = v.setValue(newValue)
}
Run Code Online (Sandbox Code Playgroud)
该implicit关键字告诉Scala编译器它可以将实例转换Value为RichValue隐式实例(前提是后者在范围内).所以现在我可以将其中定义的方法RichValue应用于实例Value.例如:
def increment(v: Value[Int]): Unit = {
v.value = v.value + 1 …Run Code Online (Sandbox Code Playgroud) 对于一个项目,我需要使用特定的JVM选项(以及一些内存/ gc选项)启动SBT - 但我不一定要将这些相同的选项应用于我拥有的每个SBT项目.-Dfile.encoding=UTF-8
我已经看到了(在sbt-extras中)对.sbtopts(特定于项目的SBT命令行选项)和.jvmopts(项目特定的SBT JVM选项)文件的引用(如果在SBT项目的根目录中找到),但标准的Windows版本的SBT(我使用的是版本0.13.1)似乎忽略了它们.
(sbt-extras方法对我很有吸引力,因为假设.sbtopts并且.jvmopts在版本控制中进行跟踪,那么希望构建项目的人需要进行零SBT配置.)
是否有当前机制来指定跨平台工作的特定于项目的SBT选项?
更新:由于我原来提出这个问题,.sbtopts而.jvmopts现在的标准部分的Linux版本的SBT,和SBT-额外不再需要.但是,Windows版本仅支持.jvmopts和不识别.sbtopts.
我正在使用Scala Cats库中的State monad来以功能方式构成命令转换的命令式序列。
我的实际用例非常复杂,因此,为简化起见,请考虑以下最小问题:存在一种Counter状态,其计数值可能会递增或递减;但是,如果计数变为负数或溢出,则表示错误。万一遇到错误,我需要在发生错误时保留状态,并有效地停止处理后续的状态转换。
我使用type,使用每个状态转换的返回值报告任何错误Try[Unit]。成功完成的操作将返回新状态加该值Success(()),而失败将返回现有状态以及包装在其中的异常Failure。
注意:显然,遇到错误时,我可以抛出异常。但是,这将违反引用透明性,并且还需要我做一些额外的工作才能将计数器状态存储在抛出的异常中。我也打折了使用a Try[Counter]作为状态类型(而不是just Counter),因为我不能使用它来跟踪失败和失败状态。我尚未探讨的一种选择是使用(Counter, Try[Unit])元组作为状态,因为这似乎太麻烦了,但是我愿意提出建议。
import cats.data.State
import scala.util.{Failure, Success, Try}
// State being maintained: an immutable counter.
final case class Counter(count: Int)
// Type for state transition operations.
type Transition[M] = State[Counter, Try[M]]
// Operation to increment a counter.
val increment: Transition[Unit] = State {c =>
// If the count is at its maximum, incrementing it …Run Code Online (Sandbox Code Playgroud) 直到最近,我的理解是下面的两个Scala语句是可以互换的.
expr.op(arg1, arg2,...)
expr op (arg1, arg2,...)
Run Code Online (Sandbox Code Playgroud)
但是我正在玩scala meta,看看它们产生的AST,
Term.Apply(Term.Select(<exprTerm>, Term.Name("op")), Seq(<argTerm1>, <argTerm2>,...))
Term.ApplyInfix(<exprTerm>, Term.Name("op"), Nil, Seq(<argTerm1>, <argTerm2>,...))
Run Code Online (Sandbox Code Playgroud)
并Nil在AST中找到了中缀表达式.进一步挖掘,我发现中缀选项允许类型参数:
expr op [Type1, Type2,...] (arg1, arg2,...)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我不明白他们的目的是什么.什么时候它们会有用?为什么他们允许中缀操作但不允许"应用选择"操作(expr.op(arg1, arg2,...))?
如果我使用该toString方法格式化double ,那么我将获得double的完整精度.例如(使用Scala语法):
java.text.MessageFormat.format ("{0}", Math.PI.toString)
Run Code Online (Sandbox Code Playgroud)
将导致包含以下内容的字符串:
3.141592653589793
Run Code Online (Sandbox Code Playgroud)
但是,此值未本地化.如果我将double值作为盒装传递Double,则为:
java.text.MessageFormat.format ("{0}", Math.PI.asInstanceOf[AnyRef])
Run Code Online (Sandbox Code Playgroud)
(AnyRef是Scala的类型,它等效于Object在爪哇),那么结果是具有截短的精度的本地化字符串:
3.142
Run Code Online (Sandbox Code Playgroud)
即使我在格式字符串中添加了更多提示,结果也是一样的:
java.text.MessageFormat.format ("{0,number}", Math.PI.asInstanceOf[AnyRef])
Run Code Online (Sandbox Code Playgroud)
通过指定自定义格式,我可以获得完整的精度:
java.text.MessageFormat.format ("{0,number,#.###############}", Math.PI.asInstanceOf[AnyRef])
Run Code Online (Sandbox Code Playgroud)
但这需要一些关于双倍大小和精度的知识.如果我打印任何双值(不仅仅是Pi),并且想要保留值的完整精度,那么这种方法意味着我必须动态地更改格式字符串 - 如果(在我的情况下)这不是很方便)格式字符串实际上是从资源包中获取的.
例如,考虑一个double值1.0e37.首先转换为字符串并使用"{0}"作为格式字符串,从而产生适当但未本地化的字符串值1.0E37.如果我把它作为Double带有格式字符串"{0,number}" 的盒子传递给我,那么我得到了荒谬的价值10,000,000,000,000,000,000,000,000,000,000,000,000.
简而言之,我似乎无法找到一个格式字符串来保留双精度的完整精度而不先将其转换为字符串 - 而这是我宁愿像瘟疫一样避免的东西.是否有一个数字格式字符串,可以输出double的完整精度作为本地化值?
更新:
只是为了澄清为什么我不想将双精度转换为字符串:
toString就我能说的而言,返回一个有效的Java双字面值.作为字符串,传递给结果时不会本地化MessageFormat.format.例如,假设我想输出值的本地化形式1234.567.toString会回来的"1234.567",MessageFormat.format会留下来的.精细.我有我的精确输出.然而,在德国,如果出现这种情况,这将更有意义"1.234,567".即使在美国/英国,如果出现这种情况,这看起来会更好"1,234.567".Integer,Boolean或任何其他非浮点基元类型传递给 …我有一个表格视图。当我更新一行的属性时,我看不到修改?例如:
implicit class PersonView(p:Person) {
val fname = new ObjectProperty(this, "fname",p.name)
}
Run Code Online (Sandbox Code Playgroud)
在我的表格视图中
lazy val tableLines = ObservableBuffer(persView)
val personTable = new TableView[PersonView](tableLines) {
columns ++= List(
new TableColumn[PersonView, String] {
text = "Name"
cellValueFactory = _.value.fname
cellFactory = { _ =>
new TableCell[PersonView, String] {
item.onChange { (_, _, newValue) => text = newValue }
}
}
}
)
}
Run Code Online (Sandbox Code Playgroud)
它工作正常,但是当我更新名称时,我在 GUI 中看不到它。
这是一个奇怪的情况:
如果我注释掉feed_usingExplicitTypeClassInstance下面的调用,那么我会收到编译器错误.
非常令人费解.任何解释?
我的意思是,我注释掉一个函数调用(它没有返回任何值),然后代码不再编译?
在理论上这应该是可能的吗?在任何编程语言?
我的意思是我评论出类似的东西println("hello")然后代码不再编译?
当然,如果我将注释掉一个声明或者其他内容,但是调用一个不返回任何内容的函数,那将是可以理解的.
object AnimalFeeder extends App {
def feed_usingExplicitTypeClassInstance[AnimalInstance]
(animalTypeClass: AnimalTypeClass[AnimalInstance])
(food: animalTypeClass.FoodThatAnimalLikes) =
{
animalTypeClass.feed(food)
}
def feed_usingImplicitTypeClassInstance[AnimalInstance, Food]
(food: Food)
(implicit animalTypeClass: AnimalTypeClass.Aux[Food,AnimalInstance]) =
{
animalTypeClass.feed(food)
}
// If I comment out this line, THEN !, I get an error !!!! How ???
feed_usingExplicitTypeClassInstance(AnimalTypeClass.CatInstance)(new CatFood())
feed_usingImplicitTypeClassInstance(new CatFood)
}
trait Food {
def eat(): Unit
}
trait AnimalTypeClass[AnimalInstance] {
type FoodThatAnimalLikes <: Food
def feed(f: FoodThatAnimalLikes) = …Run Code Online (Sandbox Code Playgroud) 我在SBT中有一个多项目Scala构建,其中我有一个根项目,它有效地聚合了两个子项目:一个宏库和一个使用该宏库的核心库.
我正在使用优秀的sbt-unidoc插件scaladoc为整个库(宏+核心组合)创建单个统一的API.
不幸的是,sbt-unidoc有一些限制.例如,默认情况下,它不会挂钩到doc任务,并且其输出将放在目标目录的unidoc文件夹中,而不是api文件夹中.这些组合可防止在执行publish或publishLocal命令时生成和打包生成的文档.幸运的是(并且由于GitHub网站上提出的问题),有一个简单的解决方案:inkytonicsbt-unidoc
lazy val customUnidocSettings = unidocSettings ++ Seq (
doc in Compile := (doc in ScalaUnidoc).value,
target in unidoc in ScalaUnidoc := crossTarget.value / "api"
)
Run Code Online (Sandbox Code Playgroud)
然后在根项目中使用这些设置:
lazy val macro = (project in file ("macro")).
settings (
name = "foo-macro"
)
lazy val core = (project in file ("core")).
settings (
name = "foo-core"
).
dependsOn …Run Code Online (Sandbox Code Playgroud) 我想在我的ubuntu中安装SBT 0.13.6版本.为此,我执行以下步骤:
wget http://dl.bintray.com/sbt/debian/sbt-0.13.6.deb
sudo dpkg -i sbt-0.13.6.deb
sudo apt-get update
sudo apt-get install sbt
Run Code Online (Sandbox Code Playgroud)
安装后,当我检查sbt版本时,它显示版本1.0.3.
这是命令:
hadoop@localhost:~$ sbt about
Getting org.scala-sbt sbt 1.0.3 ...
:: retrieving :: org.scala-sbt#boot-app
confs: [default]
69 artifacts copied, 0 already retrieved (22027kB/913ms)
Getting Scala 2.12.4 (for sbt)...
:: retrieving :: org.scala-sbt#boot-scala
confs: [default]
5 artifacts copied, 0 already retrieved (18986kB/225ms)
[info] Loading project definition from /home/hadoop/project
[info] Set current project to hadoop (in build file:/home/hadoop/)
[info] This is …Run Code Online (Sandbox Code Playgroud) 我想写一个算法来反转scala中的数字
我没有背景
object Main {
def main(args : Array[String]){
println(reverse(-136))
}
//Par defaut les paramètres d'une fonction scala sont immutables
def reverse(x : Int):Int={
var x1:Int = Math.abs(x)
var rev:Int = 0;
while (x1 > 0){
var pop:Int = x1 % 10
x1 /=10
if(rev > Int.MaxValue/10 || ((rev eq Int.MaxValue/ 10) && pop > 7)) 0.##
if (rev < Int.MinValue / 10 || ((rev eq Int.MinValue / 10) && pop < -8)) 0.##
rev = (rev * 10) + …Run Code Online (Sandbox Code Playgroud) scala ×9
sbt ×3
double ×1
java ×1
javafx ×1
scala-cats ×1
scaladoc ×1
scalafx ×1
scalameta ×1
state-monad ×1
value-class ×1
version ×1