[SCALA] 스칼라 - 가변 (VAR)에있어서의 파라미터를 참조
SCALA스칼라 - 가변 (VAR)에있어서의 파라미터를 참조
편집 : 나는 여기 upvotes가 계속. 그냥 기록을 위해, 나는 더 이상이 중요하다고 생각합니다. 내가 그것을 게시 이후 나는 그것을 필요로하지 않았습니다.
나는 스칼라에서 다음을 수행하고 싶습니다 ...
def save(srcPath: String, destPath: String) {
if (!destPath.endsWith('/'))
destPath += '/'
// do something
}
...하지만 난 destPath가 발입니다 beacuse 수 없습니다. VAR로 destPath를 선언 할 수있는 방법이 있습니까?
참고 :이 비슷한 질문이 있지만 영업 이익의 모든 단지 배열을 수정하고 싶었다.
다음과 같은 조언을하지 마십시오 :
나는 명령형 프로그래밍에서 유효 생각 (스칼라 오른쪽 모두 허용?)와 tmpDestPath 같은 것을 추가하는 것은 단지 혼란을 추가합니다.
편집 :하지 오해. 나는 문자열을 변경할 수 없습니다 내가 호출자의 데이터를 수정하지 않기 때문에 내가 참조에 대한 참조를하지 않으려는 것을 알고있다. 난 그냥 발신자가 내 문자열로 저를 준 문자열에 대한 로컬 참조 수정하려면 (예를. 오리지널 + '/'). 난 단지 현재의 방법의 범위에 그 값을 수정할. 이 자바에서 완벽하게 유효 봐 :
void printPlusOne(int i) {
i++;
System.out.println("i is: " + i);
System.out.println("and now it's same: " + i);
}
나는 새로운 변수를 만들 필요가 없습니다 그리고 난 두 번 내가 + 1 계산 할 필요가 없습니다.
해결법
-
==============================
1.당신은 할 수 없습니다.
당신은 할 수 없습니다.
당신은 여분의 VAR를 선언해야 (또는 더 많은 기능 스타일을 :-) 사용) 것입니다.
단순한 예 :
def save(srcPath: String, destPath: String) { val normalizedDestPath = if (destPath.endsWith('/')) destPath else destPath + '/' // do something with normalizedDestPath }
-
==============================
2.JVM은 당신이 정확하게 당신이 원하는 일을 할 수 없도록, (당신이 C ++에서이 작업을 수행 할 것입니다 방법입니다) 통과 참조에 의한 개체에 대한 포인터를 허용하지 않습니다.
JVM은 당신이 정확하게 당신이 원하는 일을 할 수 없도록, (당신이 C ++에서이 작업을 수행 할 것입니다 방법입니다) 통과 참조에 의한 개체에 대한 포인터를 허용하지 않습니다.
하나의 옵션은 새 값을 반환하는 것입니다 :
def save(srcPath: String, destPath: String): String = { val newPath = (if (!destPath.endsWith("/")) destPath+'/' else destPath) // do something newPath }
또 다른 래퍼를 만드는 것입니다 :
case class Mut[A](var value: A) {} def save(srcPath: String, destPath: Mut[String]) { if (!destPath.value.endsWith("/")) destPath.value += '/' // do something }
어떤 사용자가 다음 방식에 사용해야합니다. (물론, 그들은 "/ 여기에"(저장 유혹 할 것이다, 무트 ( "/이"))에 변경을 던져, 그러나 이것은 항상 사실입니다 것이다 패스 별 기준 함수 인수).
편집 : 당신은 제안하는 비 전문 프로그래머들 사이에서 혼란의 가장 큰 소스 중 하나 무엇인지. 만약 함수의 인수를 수정할 때 즉,하면 로컬 복사본 (통과하여 값) 또는 원본 (패스 별 참조)를 수정 있습니까? 당신도 수정할 수없는 경우가 꽤 당신이 그 아무것도 로컬 복사본입니다 분명하다.
그냥 그런 식으로 않습니다.
val destWithSlash = destPath + (if (!destPath.endsWith("/")) "/" else "")
그것은 가치가 실제로 무슨 일이 일어나고 있는지에 대한 혼란의 부족입니다.
-
==============================
3.당신도 슬래시마다 추가에 대해 걱정할 필요가 없습니다 어쩌면 당신은, 당신을 위해 일을하는 타입 시스템을 얻을 수 있습니다 :
당신도 슬래시마다 추가에 대해 걱정할 필요가 없습니다 어쩌면 당신은, 당신을 위해 일을하는 타입 시스템을 얻을 수 있습니다 :
class SlashString(s: String) { override val toString = if (s endsWith "/") s else s + "/" } implicit def toSlashString(s: String) = new SlashString(s)
지금 당신은 입력 문자열을 변경 전혀 코드가 필요하지 않습니다
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/
사실, 시작시 설정의 비트가있다, 그러나 이것은 버전 2.10에서 암시 적 클래스와 덜 그렇게 될 것입니다, 그리고 당신이 걱정하고 있었는지했다 방법, 모든 혼란을 제거합니다.
-
==============================
4.String 객체는 스칼라 (자바)에서 변경할 수 있습니다. 내가 생각할 수있는 대안은 다음과 같습니다 :
String 객체는 스칼라 (자바)에서 변경할 수 있습니다. 내가 생각할 수있는 대안은 다음과 같습니다 :
두 번째 시나리오에서는 당신이 뭔가를 같이 할 것이다 :
def save(srcPath: String, destPath: StringBuilder) { if (!destPath.toString().endsWith("/")) destPath.append("/") // do something // }
편집하다
만약 내가 제대로 이해하고, 로컬 변수로 인수를 사용하고 싶습니다. 모든 메소드 인수가 스칼라에서 발의이기 때문에 당신은 할 수 없습니다. 할 수있는 유일한 방법은 먼저 지역 변수에 복사하는 것입니다 :
def save(srcPath: String, destPath: String) { var destP = destPath if (!destP.endsWith("/")) destP += "/" // do something // }
-
==============================
5.여기에 몇 가지 제안입니다 :
여기에 몇 가지 제안입니다 :
1) 비트 함수를 업데이트
def save(srcPath: String, destPath: String) { var dp = destPath if (!dp.endsWith('/')) dp+= '/' // do something, but with dp instead of destPath }
2) 저장 호출하기 전에 사용하는 유틸리티 함수를 만듭니다
def savedPath(path: String) = if(path.endsWith("/")) path else path + "/" //call your save method on some path val myDestPath = ... val srcPath = ... save(srcPath, savedPath(myDestPath))
-
==============================
6.아니,이 스칼라에서 허용하지 않는다. 기타 (모든 좋은) 약간 낮은 수준의 해결 방법을 설명했다,하지만 난 더 높은 수준의 하나를 추가합니다. 문자열 정규화 목적의 바로 이런 종류의, 나는 접미사, 접두사, removeSuffix 및 removePrefix 같은 방법으로 scala.String에 포주 확장 주위를 유지한다. 접미사와 접두사 추가하거나 접미사 나 접두사가 이미 존재하지 않는 한, 다른에 하나의 문자열을 앞에 추가. 그것은 현재의 경우 removeSuffix 및 removePrefix는 끝에서 하나의 문자열을 제거하거나 다른의 시작, 명백한을한다. 사용 사례가 기록 될 것입니다
아니,이 스칼라에서 허용하지 않는다. 기타 (모든 좋은) 약간 낮은 수준의 해결 방법을 설명했다,하지만 난 더 높은 수준의 하나를 추가합니다. 문자열 정규화 목적의 바로 이런 종류의, 나는 접미사, 접두사, removeSuffix 및 removePrefix 같은 방법으로 scala.String에 포주 확장 주위를 유지한다. 접미사와 접두사 추가하거나 접미사 나 접두사가 이미 존재하지 않는 한, 다른에 하나의 문자열을 앞에 추가. 그것은 현재의 경우 removeSuffix 및 removePrefix는 끝에서 하나의 문자열을 제거하거나 다른의 시작, 명백한을한다. 사용 사례가 기록 될 것입니다
val normalizedPath = destPath.addSuffix("/")
당신은 데이터 분석 또는 파일 작업의 무리를 할 경우, 이러한 방법은 당신이 이제까지 그들없이했다는 것을 믿지 않을 것이다 너무 편리합니다.
-
==============================
7.나는이 오래된 질문 알아요,하지만 당신은 아마도 인수 이름을 다시 사용하려는 경우 :
나는이 오래된 질문 알아요,하지만 당신은 아마도 인수 이름을 다시 사용하려는 경우 :
def save(srcPath: String, destPath: String) { ((destPath: String) => { // do something })(if (!destPath.endsWith('/')) destPath + '/' else destPath) }
from https://stackoverflow.com/questions/9535821/scala-mutable-var-method-parameter-reference by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] Scalatest - 테스트하는 방법에 println (0) | 2019.11.27 |
---|---|
[SCALA] 스칼라에서; 나는 응용 프로그램의 특성을 사용해야합니까? (0) | 2019.11.27 |
[SCALA] 스칼라지도 자바지도로 변환 (0) | 2019.11.27 |
[SCALA] CSRF 폼에 대한 AJAX POST 요청에 토큰에 따라 어떻게 전달하는 방법? (0) | 2019.11.27 |
[SCALA] 스칼라에서 열거 순열에 코드 (0) | 2019.11.27 |