我在下面的Scala程序中发现了一种奇怪的东西(很抱歉包含所有代码,但你会明白我为什么要添加它):
object md2html extends App {
private val DEFAULT_THEME = Themes.AMAZON_LIGHT
private val VALID_OPTIONS = Set("editorTheme", "logo", "style")
try {
// some code 1
} catch {
case t: Throwable => t.printStackTrace(); exitWithError(t.getMessage)
}
// some code 2 (method definitions only)
private def parseOption(key: String, value: String) = {
println(key + " " + VALID_OPTIONS)
if (! Set("theme","editorTheme", "logo", "style").contains(key)) exitWithError(s"$key is not a valid option")
if (key == "theme") Themes(value).toMap else Map(key.drop(2) -> value)
}
// some code 3 …Run Code Online (Sandbox Code Playgroud) 我偶然发现了Predef.StringCanBuildFrom令人惊讶的实现,这打破了我CanBuildFrom在代码中所做的假设.这是实施:
implicit def stringCanBuildFrom: CanBuildFrom[String, Char, String] =
new CanBuildFrom[String, Char, String] {
def apply(from: String) = apply()
def apply() = mutable.StringBuilder.newBuilder
}
Run Code Online (Sandbox Code Playgroud)
apply(String)简单地忽略参数似乎完全不自然.对我来说,正确的实施应该是
implicit def stringCanBuildFrom: CanBuildFrom[String, Char, String] =
new CanBuildFrom[String, Char, String] {
def apply(from: String) = apply() ++= from
def apply() = mutable.StringBuilder.newBuilder
}
Run Code Online (Sandbox Code Playgroud)
但这似乎是微不足道的,以至于我无法相信我是那个因为语言存在而发现它的人.我很想为此开一个问题,但是如果我错过任何没有理由不做我的建议,请告诉我!
我正在将一个项目从 Scala 2.12.1 迁移到 2.13.6,发现SeqView#flatMap现在返回一个View,它没有distinct方法。因此,我有一段代码不再编译:
val nodes = debts.view
.flatMap { case Debt(from, to, _) => List(from, to) }
.distinct
.map(name => (name, new Node(name)))
.toMap
Run Code Online (Sandbox Code Playgroud)
有一个愚蠢的方法来修复它,将视图转换为 seq,然后再转换回视图:
val nodes = debts.view
.flatMap { case Debt(from, to, _) => List(from, to) }.toSeq.view
.distinct
.map(name => (name, new Node(name)))
.toMap
Run Code Online (Sandbox Code Playgroud)
然而,这显然不太好,因为它强制收集视图,而且必须在类型之间来回切换也是非常不优雅的。我找到了另一种方法来修复它,即使用LazyList:
val nodes = debts.to(LazyList)
.flatMap { case Debt(from, to, _) => List(from, to) }
.distinct
.map(name => (name, new Node(name)))
.toMap
Run Code Online (Sandbox Code Playgroud)
这就是我想要的,它基本上表现得像 …
我在Scala中看到了一个奇怪的片段,我不太明白.对我来说,Scala中的赋值返回Unit,与Java不同,它返回已影响值的变量的类型.但是,让我们考虑这个类:
case class C(i: Int) {
def f = C(i = i + 10)
}
Run Code Online (Sandbox Code Playgroud)
编译完全没问题,这很奇怪!工厂方法C.apply需要一个Int,而我传递它似乎是一个类型的赋值Unit.顺便说一句,如果我删除赋值只是让表达式,它似乎有完全相同的行为.
我们现在试试吧:
case class C(i: Int) {
def f = {
i = i + 10
C(i = i + 10)
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,现在这是我所知道的世界:i是一个val,然后你不能改变它,所以i = i + 10不编译.但是,C(i = i + 10)仍然编译而不抱怨.这怪异是什么?这有什么理由存在吗?
我正在阅读有关使用关键字验证方法前置条件和后置条件的Oracle 文档。assert
该文档说,可以使用assert关键字来验证public方法的后置条件,但您应该只使用assert关键字来验证private方法的前置条件。
为什么是这样?
我运行了下面的片段,输出了Hey David.
public class Test {
public String name;
public Test(String name) {
this.name = name;
}
public class A {
public String toString() {
return "Hey " + name;
}
}
public static void main(String[] args) {
Test test = new Test("David");
A a = test.new A();
test = null;
System.out.println(a);
}
}
Run Code Online (Sandbox Code Playgroud)
我还测试了System.gc()在打印之前打电话a但我不确定它实际上是立即触发了一个完整的GC,所以它可能不相关.说实话,在运行代码之前,我不知道它应该发生什么,因为实际的行为对我来说似乎是逻辑的,就像NPE被抛出一样,因为它name被附加到一个无效的实例.
你能解释一下我们为什么观察它以及封闭类型的确切工作实例吗?
我创建了一个简单的注释类:
@Retention(RUNTIME)
public @interface Column {
public String name();
}
Run Code Online (Sandbox Code Playgroud)
我在这样的一些类中使用它:
public class FgnPzt extends Point {
public static final String COLUMN_TYPE = "type";
@Column(name=COLUMN_TYPE)
protected String type;
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以遍历声明的字段并获得这样的注释:
for (Field field : current.getDeclaredFields()) {
try {
Column c = field.getAnnotation(Column.class);
[...]
} catch(Exception e) {
[...]
}
}
Run Code Online (Sandbox Code Playgroud)
如何在type不迭代类的声明字段的情况下直接通过其注释名称获取字段?
我试图找出如何在铸造后将剩余部分存储到整数.
例如:
int amount = 274
int numDollars = amount/100;
//this returns 2 for numDollars, but clears out the .74, and I would like to store 74 to amount
Run Code Online (Sandbox Code Playgroud)
这看起来有可能吗?
//What will happen when you attempt to compile and run the following code?
public class TestThread extends Thread {
public static void main(String[] args) {
new TestThread().start();
new TestThread().start();
}
public void run() {
Safe s1 = new Safe("abc");
Safe s2 = new Safe("xyz");
}
}
class Safe {
String str;
public synchronized Safe(String s) {
str = s;
str = str.toUpperCase();
System.out.print(str + " ");
}
}
Run Code Online (Sandbox Code Playgroud)
为什么这个方法公共同步安全(String S)给我一个编译错误?我知道我们无法同步变量,但上面的代码出了什么问题?!?!