ตัวดำเนินการสัญลักษณ์ของ Scala ทั้งหมดหมายถึงอะไร


402

ไวยากรณ์สกาล่ามีสัญลักษณ์มากมาย เนื่องจากชื่อประเภทเหล่านี้หาได้ยากโดยใช้เสิร์ชเอ็นจิ้นรายชื่อที่ครอบคลุมจึงมีประโยชน์

สัญลักษณ์ทั้งหมดใน Scala คืออะไรและแต่ละสัญลักษณ์ทำอะไร

โดยเฉพาะอย่างยิ่งผมอยากจะรู้เกี่ยวกับ->, ||=, ++=, <=, _._, และ:::+=


4
และดัชนีของ Staircase 1st edition ที่ >> artima.com/pins1ed/book-index.html#indexanchor
Gene T

2
ที่เกี่ยวข้อง: ตัวดำเนินการตัวอักษรเทียบกับตัวอักษรและตัวเลข: stackoverflow.com/questions/7656937/…
Luigi Plinge

1
นอกจากนี้หากมี "โอเปอเรเตอร์" (ซึ่งส่วนใหญ่เป็นวิธีการที่มีชื่อคลาสไม่กี่อันที่ใช้มัด) ที่คุณไม่สามารถหาได้ใน scalex หรือหนังสือบันไดเช่น "!!" แหล่งที่น่าจะเป็น scaladocs สำหรับ akka, scalaz และ sbt
Gene T

ตัวอย่างของชื่อคลาสที่ใช้ infix (เป็นภาษาเยอรมัน) >> raichoo.blogspot.com/2010/06/spass-mit-scala-infixtypen.html
Gene T

เกี่ยวกับปัญหาในการกรองโดยเครื่องมือค้นหาsymbolhound.comยังเป็นทางเลือกที่ดี
แพทริค Refondini

คำตอบ:


526

ฉันแบ่งผู้ปฏิบัติงานเพื่อวัตถุประสงค์ในการสอนเป็นสี่ประเภท :

  • คำหลัก / สัญลักษณ์ที่สงวนไว้
  • วิธีการนำเข้าโดยอัตโนมัติ
  • วิธีการทั่วไป
  • น้ำตาล / องค์ประกอบของวากยสัมพันธ์

โชคดีที่หมวดหมู่ส่วนใหญ่มีคำถาม:

->    // Automatically imported method
||=   // Syntactic sugar
++=   // Syntactic sugar/composition or common method
<=    // Common method
_._   // Typo, though it's probably based on Keyword/composition
::    // Common method
:+=   // Common method

ความหมายที่แท้จริงของวิธีการเหล่านี้ส่วนใหญ่ขึ้นอยู่กับคลาสที่กำหนดไว้ ยกตัวอย่างเช่น<=ในIntหมายถึง"น้อยกว่าหรือเท่ากับ" อันแรก->ฉันจะยกตัวอย่างด้านล่าง ::อาจเป็นวิธีการที่กำหนดไว้List(แม้ว่ามันอาจเป็นวัตถุที่มีชื่อเดียวกัน) และ:+=อาจเป็นวิธีที่กำหนดไว้ในBufferคลาสต่างๆ

ดังนั้นเรามาดูพวกเขา

คำหลัก / สัญลักษณ์ที่สงวนไว้

มีสัญลักษณ์บางอย่างใน Scala ที่พิเศษ สองคำนี้ถือเป็นคำหลักที่เหมาะสมในขณะที่คำอื่น ๆ เป็นเพียง "สงวน" พวกเขาคือ:

// Keywords
<-  // Used on for-comprehensions, to separate pattern from generator
=>  // Used for function types, function literals and import renaming

// Reserved
( )        // Delimit expressions and parameters
[ ]        // Delimit type parameters
{ }        // Delimit blocks
.          // Method call and path separator
// /* */   // Comments
#          // Used in type notations
:          // Type ascription or context bounds
<: >: <%   // Upper, lower and view bounds
<? <!      // Start token for various XML elements
" """      // Strings
'          // Indicate symbols and characters
@          // Annotations and variable binding on pattern matching
`          // Denote constant or enable arbitrary identifiers
,          // Parameter separator
;          // Statement separator
_*         // vararg expansion
_          // Many different meanings

สิ่งเหล่านี้ล้วนเป็นส่วนหนึ่งของภาษาและสามารถพบได้ในข้อความใด ๆ ที่อธิบายภาษาได้อย่างถูกต้องเช่นScala Specification (PDF)

อันสุดท้ายขีดเส้นใต้สมควรได้รับรายละเอียดพิเศษเพราะมันใช้กันอย่างแพร่หลายและมีความหมายที่แตกต่างกันมากมาย นี่คือตัวอย่าง:

import scala._    // Wild card -- all of Scala is imported
import scala.{ Predef => _, _ } // Exception, everything except Predef
def f[M[_]]       // Higher kinded type parameter
def f(m: M[_])    // Existential type
_ + _             // Anonymous function placeholder parameter
m _               // Eta expansion of method into method value
m(_)              // Partial function application
_ => 5            // Discarded parameter
case _ =>         // Wild card pattern -- matches anything
f(xs: _*)         // Sequence xs is passed as multiple parameters to f(ys: T*)
case Seq(xs @ _*) // Identifier xs is bound to the whole matched sequence

ฉันอาจจะลืมความหมายอื่นบ้าง

วิธีการนำเข้าโดยอัตโนมัติ

ดังนั้นหากคุณไม่พบสัญลักษณ์ที่คุณต้องการในรายการด้านบนมันจะต้องเป็นวิธีการหรือส่วนหนึ่งของ แต่บ่อยครั้งที่คุณจะเห็นสัญลักษณ์และเอกสารประกอบการเรียนจะไม่มีวิธีการนั้น เมื่อสิ่งนี้เกิดขึ้นคุณกำลังมองหาองค์ประกอบของวิธีการอย่างน้อยหนึ่งวิธีหรืออย่างอื่นหรือวิธีการนั้นได้ถูกนำเข้าไปในขอบเขตหรือมีให้ผ่านการแปลงโดยนัยที่นำเข้า

เหล่านี้ยังสามารถพบได้บนScalaDoc : คุณเพียงแค่ต้องรู้จักที่จะมองหาพวกเขา หรือความล้มเหลวนั้นให้ดูที่ดัชนี (แตกหักในปัจจุบันที่ 2.9.1 แต่มีให้ทุกคืน)

รหัสสกาล่าทุกตัวมีการนำเข้าอัตโนมัติสามรายการ:

// Not necessarily in this order
import _root_.java.lang._      // _root_ denotes an absolute path
import _root_.scala._
import _root_.scala.Predef._

สองคนแรกเท่านั้นที่ทำให้ชั้นเรียนและวัตถุเดี่ยวใช้ได้ อันที่สามมีการแปลงโดยนัยและวิธีการนำเข้าทั้งหมดเนื่องจากPredefเป็นวัตถุเอง

มองเข้าไปข้างในPredefอย่างรวดเร็วแสดงสัญลักษณ์บางอย่าง:

class <:<
class =:=
object <%<
object =:=

สัญลักษณ์อื่น ๆ จะทำใช้ได้ผ่านการแปลงโดยปริยาย เพียงดูวิธีการติดแท็กด้วยการimplicitรับเป็นพารามิเตอร์วัตถุประเภทที่ได้รับวิธีการ ตัวอย่างเช่น:

"a" -> 1  // Look for an implicit from String, AnyRef, Any or type parameter

ในกรณีข้างต้น->มีการกำหนดไว้ในคลาสArrowAssocผ่านวิธีการany2ArrowAssocที่รับอ็อบเจกต์ประเภทAโดยที่Aพารามิเตอร์ประเภทไม่ได้ จำกัด ไว้ที่เมธอดเดียวกัน

วิธีการทั่วไป

ดังนั้นสัญลักษณ์จำนวนมากเป็นเพียงวิธีการในชั้นเรียน ตัวอย่างเช่นถ้าคุณทำ

List(1, 2) ++ List(3, 4)

คุณจะพบวิธีการที่++เหมาะสมใน ScalaDoc สำหรับรายการ อย่างไรก็ตามมีการประชุมหนึ่งข้อที่คุณต้องระวังเมื่อค้นหาวิธีต่างๆ วิธีการที่ลงท้ายด้วยโคลอน ( :) ผูกทางด้านขวาแทนด้านซ้าย กล่าวอีกนัยหนึ่งขณะที่การเรียกเมธอดด้านบนเทียบเท่ากับ:

List(1, 2).++(List(3, 4))

หากฉันมี1 :: List(2, 3)สิ่งนั้นจะเทียบเท่ากับ:

List(2, 3).::(1)

ดังนั้นคุณต้องดูประเภทที่พบทางด้านขวาเมื่อค้นหาวิธีที่ลงท้ายด้วยเครื่องหมายโคลอน ยกตัวอย่างเช่น

1 +: List(2, 3) :+ 4

วิธีแรก ( +:) Listผูกไปทางขวาและสามารถพบได้ใน วิธีที่สอง ( :+) เป็นเพียงวิธีการปกติและผูกไปทางซ้าย - Listอีกครั้งใน

น้ำตาล / องค์ประกอบของวากยสัมพันธ์

ดังนั้นนี่คือน้ำตาล syntactic น้ำตาลที่อาจซ่อนวิธี:

class Example(arr: Array[Int] = Array.fill(5)(0)) {
  def apply(n: Int) = arr(n)
  def update(n: Int, v: Int) = arr(n) = v
  def a = arr(0); def a_=(v: Int) = arr(0) = v
  def b = arr(1); def b_=(v: Int) = arr(1) = v
  def c = arr(2); def c_=(v: Int) = arr(2) = v
  def d = arr(3); def d_=(v: Int) = arr(3) = v
  def e = arr(4); def e_=(v: Int) = arr(4) = v
  def +(v: Int) = new Example(arr map (_ + v))
  def unapply(n: Int) = if (arr.indices contains n) Some(arr(n)) else None
}

val Ex = new Example // or var for the last example
println(Ex(0))  // calls apply(0)
Ex(0) = 2       // calls update(0, 2)
Ex.b = 3        // calls b_=(3)
// This requires Ex to be a "val"
val Ex(c) = 2   // calls unapply(2) and assigns result to c
// This requires Ex to be a "var"
Ex += 1         // substituted for Ex = Ex + 1

อันสุดท้ายเป็นสิ่งที่น่าสนใจเพราะวิธีการเชิงสัญลักษณ์ใด ๆสามารถนำมารวมกันเพื่อก่อให้เกิดวิธีการที่ได้รับมอบหมาย

และแน่นอนว่ามีชุดค่าผสมต่าง ๆ ที่สามารถปรากฏในรหัสได้:

(_+_) // An expression, or parameter, that is an anonymous function with
      // two parameters, used exactly where the underscores appear, and
      // which calls the "+" method on the first parameter passing the
      // second parameter as argument.

1
คุณหมายถึงval c = ex(2)แทนval ex(c) = 2?
Mike Stay

3
@MikeStay val ex(c) = 2ไม่ฉันไม่ได้หมายถึง
Daniel C. Sobral

โอ้มันใช้รูปแบบการจับคู่รูปแบบ ขอบคุณ
Mike Stay

=> ยังให้สถานะ 'โทรตามชื่อ' เมื่อใช้ระหว่าง: และพิมพ์ตามใน y: => Int '
Stephen W. Wright

1
บางทีเราควรพูดถึงตัวดำเนินการ: / และ: \ ดังนั้น map.foldLeft (initialVal) จึงเหมือนกับ (initialVal: / map) -: \ คือ foldRight แทน
Mr MT

24

ข้อแตกต่างหนึ่ง (ดี, IMO) ระหว่าง Scala และภาษาอื่น ๆ คือมันช่วยให้คุณตั้งชื่อวิธีการของคุณด้วยตัวละครเกือบทุกตัว

สิ่งที่คุณระบุไม่ได้เป็น "เครื่องหมายวรรคตอน" แต่วิธีธรรมดาและเรียบง่ายและพฤติกรรมของพวกเขาแตกต่างจากวัตถุหนึ่งไปยังอีก (แม้ว่าจะมีการประชุมบางส่วน)

ตัวอย่างเช่นตรวจสอบเอกสาร Scaladoc สำหรับรายการและคุณจะเห็นวิธีการบางอย่างที่คุณกล่าวถึงที่นี่

สิ่งที่ควรทราบ:

  • เวลาส่วนใหญ่ที่A operator+equal Bชุดค่าผสมแปลเป็นA = A operator Bเช่นใน||=หรือ++=ตัวอย่าง

  • วิธีการที่สิ้นสุดใน:มีความเชื่อมโยงทางด้านขวาหมายถึงการที่เป็นจริงA :: BB.::(A)

คุณจะพบคำตอบมากที่สุดโดยการดูเอกสารของสกาล่า การอ้างอิงที่นี่จะพยายามซ้ำและมันจะตกไปอย่างรวดเร็ว :)


21

คุณสามารถจัดกลุ่มเหล่านั้นก่อนตามเกณฑ์บางอย่าง ในโพสต์นี้ฉันจะอธิบายถึงตัวอักษรขีดล่างและลูกศรขวา

_._มีจุด ช่วงเวลาใน Scala แสดงการเรียกใช้เมธอดเสมอ ดังนั้นเหลือระยะเวลาที่คุณมีผู้รับและด้านขวาของมันข้อความ (ชื่อวิธีการ) ตอนนี้_เป็นสัญลักษณ์พิเศษใน Scala มีหลายโพสต์เกี่ยวกับเรื่องนี้ตัวอย่างเช่นรายการบล็อกทั้งหมดกรณีการใช้งาน นี่มันเป็นฟังก์ชั่นที่ไม่ระบุชื่อตัดสั้นว่ามันเป็นทางลัดสำหรับฟังก์ชั่นที่ใช้เวลาหนึ่งอาร์กิวเมนต์และจะเรียกวิธีการที่_เกี่ยวกับมัน ตอนนี้_ไม่ใช่วิธีที่ถูกต้องดังนั้นแน่นอนที่สุดที่คุณเห็น_._1หรือสิ่งที่คล้ายกันนั่นคือวิธีการเรียกใช้_._1ในการโต้แย้งฟังก์ชั่น _1จะ_22มีวิธีการของ tuples ซึ่งสารสกัดจากองค์ประกอบเฉพาะของขอบเขตของ ตัวอย่าง:

val tup = ("Hallo", 33)
tup._1 // extracts "Hallo"
tup._2 // extracts 33

ตอนนี้ให้สมมติว่าเป็นกรณีใช้งานสำหรับทางลัดแอปพลิเคชันฟังก์ชัน รับแผนที่ซึ่งแผนที่จำนวนเต็มกับสตริง:

val coll = Map(1 -> "Eins", 2 -> "Zwei", 3 -> "Drei")

Wooop มีเครื่องหมายวรรคตอนแปลกอีกแล้ว ยัติภังค์และมากขึ้นกว่าตัวละครซึ่งมีลักษณะคล้ายกับลูกศรขวามือTuple2เป็นผู้ประกอบการซึ่งเป็นผู้ผลิต ดังนั้นจึงไม่มีความแตกต่างในผลลัพธ์ของการเขียนอย่างใดอย่างหนึ่ง(1, "Eins")หรือ1 -> "Eins"เฉพาะที่หลังจะง่ายต่อการอ่านโดยเฉพาะในรายการของสิ่งอันดับเช่นตัวอย่างแผนที่ ->คือความมหัศจรรย์ที่ไม่เป็นเช่นผู้ประกอบการอื่น ๆ ไม่กี่ที่มีอยู่เพราะคุณมีนัยแปลงในวัตถุscala.Predefอยู่ในขอบเขต การแปลงที่เกิดขึ้นที่นี่คือ

implicit def any2ArrowAssoc [A] (x: A): ArrowAssoc[A] 

ที่ไหนArrowAssocมีวิธีการที่จะสร้าง-> Tuple2ดังนั้นจึง1 -> "Eins"เป็นการโทรที่Predef.any2ArrowAssoc(1).->("Eins")แท้จริง ตกลง. ตอนนี้กลับไปที่คำถามเดิมที่มีอักขระขีดล่าง:

// lets create a sequence from the map by returning the
// values in reverse.
coll.map(_._2.reverse) // yields List(sniE, iewZ, ierD)

ขีดล่างที่นี่ทำให้รหัสที่เทียบเท่าสั้นลงดังต่อไปนี้:

coll.map(tup => tup._2.reverse)

โปรดทราบว่าmapวิธีการของแผนที่ผ่านใน tuple ของคีย์และค่าให้กับฟังก์ชั่นการโต้แย้ง เนื่องจากเราสนใจเฉพาะค่า (สตริง) เท่านั้นเราจึงแยกค่าเหล่านั้นด้วย_2เมธอดบน tuple


+1 ฉันมีปัญหาในการพยายามเข้าใจ->วิธีการ แต่ประโยคของคุณ "ดังนั้นจึงไม่มีความแตกต่างในผลลัพธ์ของการเขียนอย่างใดอย่างหนึ่ง(1, "Eins")หรือ1 -> "Eins"" ช่วยให้ฉันเข้าใจไวยากรณ์และการใช้งานของมัน
Jesse Webb

fyi ลิงค์บล็อกของคุณตาย
still_learning

15

นอกเหนือจากคำตอบที่ยอดเยี่ยมของ Daniel และ 0__ ฉันต้องบอกว่า Scala เข้าใจUnicode analogs สำหรับสัญลักษณ์บางอย่างดังนั้นแทนที่จะเป็น

for (n <- 1 to 10) n % 2 match {
  case 0 => println("even")
  case 1 => println("odd")
}

หนึ่งอาจเขียน

for (n ← 1 to 10) n % 2 match {
  case 0 ⇒ println("even")
  case 1 ⇒ println("odd")
}

10

เกี่ยวกับ::มีรายการStackoverflowอื่นซึ่งครอบคลุม::เคส ในระยะสั้นจะใช้ในการสร้างListsโดย ' consing ' องค์ประกอบหัวและรายการหาง มันเป็นทั้งชั้นเรียนซึ่งแสดงถึงรายการ cons'ed และซึ่งสามารถใช้เป็นตัวแยก แต่ส่วนใหญ่มันเป็นวิธีการในรายการ เมื่อปาโบลเฟอร์นันเดซชี้ให้เห็นเนื่องจากมันสิ้นสุดในลำไส้ใหญ่มันเป็นความสัมพันธ์ที่ถูกต้องซึ่งหมายความว่าผู้รับของการเรียกใช้เมธอดนั้นอยู่ทางขวาและการโต้เถียงทางด้านซ้ายของโอเปอเรเตอร์ วิธีการที่คุณสามารถแสดงความหรูหรา Consing เป็นprependingองค์ประกอบหัวใหม่ไปยังรายการที่มีอยู่:

val x = 2 :: 3 :: Nil  // same result as List(2, 3)
val y = 1 :: x         // yields List(1, 2, 3)

สิ่งนี้เทียบเท่า

val x = Nil.::(3).::(2) // successively prepend 3 and 2 to an empty list
val y = x.::(1)         // then prepend 1

ใช้เป็นวัตถุแยกเป็นดังนี้:

def extract(l: List[Int]) = l match {
   case Nil          => "empty"
   case head :: Nil  => "exactly one element (" + head + ")"
   case head :: tail => "more than one element"
}

extract(Nil)          // yields "empty"
extract(List(1))      // yields "exactly one element (1)"
extract(List(2, 3))   // yields "more than one element"

ดูเหมือนว่าตัวดำเนินการที่นี่ แต่เป็นอีกวิธีหนึ่งในการเขียน (อ่านได้มากกว่า)

def extract2(l: List[Int]) = l match {
   case Nil            => "empty"
   case ::(head, Nil)  => "exactly one element (" + head + ")"
   case ::(head, tail) => "more than one element"
}

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับแยกในโพสต์นี้


9

<=เป็นเหมือนที่คุณจะ "อ่าน" มัน: 'น้อยกว่าหรือเท่ากับ' ดังนั้นมันจึงเป็นโอเปอเรเตอร์ทางคณิตศาสตร์ในรายการ<(น้อยกว่า?), >(มากกว่าหรือไม่), ==(เท่ากับ?), !=(ไม่เท่ากับ?), <=(น้อยกว่าหรือเท่ากับ?) และ>=(มากกว่า หรือเท่ากับ?)

นี้จะต้องไม่สับสนด้วย=>ซึ่งเป็นชนิดของลูกศรขวามือคู่ที่ใช้ในการแยกรายการอาร์กิวเมนต์จากร่างกายของฟังก์ชันและการแยกสภาพการทดสอบในการจับคู่แบบ (กcaseบล็อก) ออกจากร่างกายดำเนินการเมื่อการแข่งขันเกิดขึ้น . คุณสามารถดูตัวอย่างนี้ได้ในคำตอบก่อนหน้านี้ของฉัน ครั้งแรกที่ใช้ฟังก์ชั่น:

coll.map(tup => tup._2.reverse)

ซึ่งเป็นตัวย่อแล้วในขณะที่ประเภทจะถูกละเว้น ฟังก์ชั่นการติดตามจะเป็น

// function arguments         function body
(tup: Tuple2[Int, String]) => tup._2.reverse

และการจับคู่รูปแบบใช้:

def extract2(l: List[Int]) = l match {
   // if l matches Nil    return "empty"
   case Nil            => "empty"
   // etc.
   case ::(head, Nil)  => "exactly one element (" + head + ")"
   // etc.
   case ::(head, tail) => "more than one element"
}

4
การหลีกเลี่ยงความสับสนนี้คือเหตุผลที่ฉันตัดสินใจเริ่มใช้อักขระ unicode สำหรับลูกศรคู่ด้านขวา (\ U21D2), ลูกศร "แผนที่" ลูกศรขวา (\ U2192), และลูกศรซ้าย "ใน" ลูกศร (\ U2190) สกาล่าสนับสนุนสิ่งนี้ แต่ฉันก็ยังสงสัยอยู่เล็กน้อยจนกว่าฉันจะลองมันซักพัก เพียงแค่ค้นหาวิธีการผูกจุดรหัสเหล่านี้กับคีย์ผสมที่สะดวกในระบบของคุณ มันง่ายมากใน OS X.
Connor Doyle

5

ฉันถือว่า IDE สมัยใหม่เป็นสิ่งสำคัญสำหรับการทำความเข้าใจโครงการขนาดใหญ่ เนื่องจากโอเปอเรเตอร์เหล่านี้เป็นวิธีการในแนวคิด Intellij ฉันเพียงแค่ควบคุมคลิกหรือควบคุม -b ลงในคำจำกัดความ

คุณสามารถควบคุมคลิกขวาในโอเปอเรเตอร์ cons (: :) และจบลงที่ scala javadoc โดยพูดว่า "เพิ่มองค์ประกอบที่จุดเริ่มต้นของรายการนี้" ในโอเปอเรเตอร์ที่ผู้ใช้กำหนดเองสิ่งนี้จะมีความสำคัญยิ่งขึ้นเนื่องจากสามารถกำหนดได้โดยนัยในการค้นหายาก ... IDE ของคุณรู้ว่าที่ใดที่ถูกกำหนดโดยปริยาย


4

เพียงเพิ่มคำตอบที่ยอดเยี่ยมอื่น ๆ สกาล่าเสนอตัวดำเนินการสัญลักษณ์สองตัวที่ถูกวิพากษ์วิจารณ์บ่อยครั้งตัวดำเนินการ/:( foldLeft) และ:\( foldRight) ซึ่งเป็นตัวเชื่อมโยงแรก ดังนั้นข้อความทั้งสามต่อไปนี้จึงเทียบเท่ากัน:

( 1 to 100 ).foldLeft( 0, _+_ )
( 1 to 100 )./:( 0 )( _+_ )
( 0 /: ( 1 to 100 ) )( _+_ )

เช่นเดียวกับสามสิ่งนี้:

( 1 to 100 ).foldRight( 0, _+_ )
( 1 to 100 ).:\( 0 )( _+_ )
( ( 1 to 100 ) :\ 0 )( _+_ )

2

สืบทอด Scala ที่สุดของการดำเนินการทางคณิตศาสตร์ของ Java ซึ่งรวมถึงค่าที่เหมาะสมหรือ|(ตัวอักษรท่อเดียว) ค่าที่เหมาะสมและ&ค่าบิต แต่เพียงผู้เดียวหรือ^เช่นเดียวกับตรรกะ (บูล) หรือ||(ตัวอักษรสองท่อ) &&และตรรกะและ น่าสนใจคุณสามารถใช้ตัวดำเนินการตัวเดียวในbooleanดังนั้นตัวดำเนินการทางตรรกะ java'ish ซ้ำซ้อนทั้งหมด:

true && true   // valid
true & true    // valid as well

3 & 4          // bitwise-and (011 & 100 yields 000)
3 && 4         // not valid

ดังที่ได้กล่าวไว้ในโพสต์อื่นการโทรที่ลงท้ายด้วยเครื่องหมายเท่ากับ=จะได้รับการแก้ไข (หากวิธีที่ไม่มีชื่อนั้นมีอยู่จริง!) โดยการโอนสิทธิต่อใหม่:

var x = 3
x += 1         // `+=` is not a method in `int`, Scala makes it `x = x + 1`

'การตรวจสอบซ้ำ' นี้ช่วยให้สามารถแลกเปลี่ยนความไม่แน่นอนสำหรับคอลเล็กชันที่ไม่เปลี่ยนรูปแบบได้อย่างง่ายดาย:

val m = collection.mutable.Set("Hallo")   // `m` a val, but holds mutable coll
var i = collection.immutable.Set("Hallo") // `i` is a var, but holds immutable coll

m += "Welt" // destructive call m.+=("Welt")
i += "Welt" // re-assignment i = i + "Welt" (creates a new immutable Set)

4
PS มีความแตกต่างระหว่างการใช้เทียบกับผู้ประกอบการตัวละครเดียวสองครั้งที่ booleans-อดีตมีความกระตือรือร้น (เงื่อนไขทั้งหมดได้รับการประเมิน) ยุติหลังต้นถ้าบูลีนส่งผลให้เป็นที่รู้จักกัน: true | { println( "Icke" ); true }⇒พิมพ์! true || { println( "Icke" ); true }ไม่พิมพ์!
0__
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.