wok*_*oky 40 variables parameters methods scala
编辑:我一直在这里投票.仅仅为了记录,我不再认为这很重要.自从我发布之后我就不需要了.
我想在Scala中做以下...
def save(srcPath: String, destPath: String) {
if (!destPath.endsWith('/'))
destPath += '/'
// do something
}
Run Code Online (Sandbox Code Playgroud)
......但我不能说destPath是val.有没有办法声明destPath为var?
注意:有类似的问题,但在所有这些问题中OP只是想修改数组.
请不要建议以下内容:
改变输入参数通常被认为是糟糕的风格,并且使得更难以推理代码.
我认为它在命令式编程中是有效的(Scala允许两者,对吗?)并添加类似tmpDestPath添加杂乱的东西.
编辑:不要误解.我知道字符串不可变,我不想引用引用,因为我不想修改调用者的数据.我只想修改调用者给我的字符串的本地引用(例如,orig +'/').我想仅在当前方法的范围内修改该值.看,这在Java中是完全有效的:
void printPlusOne(int i) {
i++;
System.out.println("i is: " + i);
System.out.println("and now it's same: " + i);
}
Run Code Online (Sandbox Code Playgroud)
我不必创建新变量,我不必两次计算i + 1.
Jea*_*let 29
你不能.
你必须声明一个额外的var(或使用更实用的风格:-)).
简单的例子:
def save(srcPath: String, destPath: String) {
val normalizedDestPath =
if (destPath.endsWith('/')) destPath
else destPath + '/'
// do something with normalizedDestPath
}
Run Code Online (Sandbox Code Playgroud)
JVM不允许指向对象的指针传递(这是你在C++中这样做的方式),所以你不能完全按照自己的意愿去做.
一种选择是返回新值:
def save(srcPath: String, destPath: String): String = {
val newPath = (if (!destPath.endsWith("/")) destPath+'/' else destPath)
// do something
newPath
}
Run Code Online (Sandbox Code Playgroud)
另一个是创建一个包装器:
case class Mut[A](var value: A) {}
def save(srcPath: String, destPath: Mut[String]) {
if (!destPath.value.endsWith("/")) destPath.value += '/'
// do something
}
Run Code Online (Sandbox Code Playgroud)
那些用户将在进入的路上必须使用.(当然,他们会被诱惑save("/here",Mut("/there"))哪些会丢弃更改,但是传递引用函数参数总是如此.)
编辑:你提出的建议是非专业程序员之间最大的困惑之一.也就是说,当您修改函数的参数时,您是修改本地副本(按值传递)还是原始(按引用传递)?如果您甚至无法修改它,很明显您所做的任何事情都是本地副本.
就这样做吧.
val destWithSlash = destPath + (if (!destPath.endsWith("/")) "/" else "")
Run Code Online (Sandbox Code Playgroud)
值得对实际发生的事情缺乏困惑.
也许您可以让类型系统为您完成工作,因此您甚至不必担心每次都添加斜杠:
class SlashString(s: String) {
override val toString = if (s endsWith "/") s else s + "/"
}
implicit def toSlashString(s: String) = new SlashString(s)
Run Code Online (Sandbox Code Playgroud)
现在您根本不需要任何代码来更改输入String:
def save(srcPath: String, destPath: SlashString) {
printf("saving from %s to %s", srcPath, destPath)
}
val src: String = "abc"
val dst: String = "xyz"
scala> save(src, dst)
saving from abc to xyz/
Run Code Online (Sandbox Code Playgroud)
确实,在开始时有一些设置,但是对于2.10版本中的隐式类,这将会更少 - 并且它会消除方法中的所有混乱,这是您所担心的.
| 归档时间: |
|
| 查看次数: |
33565 次 |
| 最近记录: |