Welcome to the Scala discussion QQ group 212859367, and Lianle together to discuss learning!
Single Case Type
Example:
class Document{ def setTitile(title: String) = {...; this} def setAuthor(author: String) = {...; this} ...}val atticle.setTitle("whatever floats your boat").setAuthor("lianle")
If the above class has subclasses, the problem occurs:
class Book extends Document{ def addChapter(chapter: String) = {...; this} ...}//调用出错:val book = new Bookbook.setTitle("Scala for the impatient").addChapter("chapter1")
Analysis Reason:
Since Settitle returns this; Scala infers the return type as document, but the document does not have a Addchapter method.
Workaround:
def setTitle(title: String) : this.type = {...; this}//添加单例类型
Type projection
Example:
import scala.collection.mutable.ArrayBufferclass Network { class Member(val name: String) { valnew ArrayBuffer[Member] } privatevalnew ArrayBuffer[Member] def join(name: String) = { valnew Member(name) members += m m }}
Define two networks:
valnew Networkvalnew Network
The following actions will cause an error:
val fred = chatter.join("Fred") //类型为chatter.Memberval barney = myFace.join("Barney")//类型为myFace.Memberfred.contacts += barney //报错
Solution:
class Network { class Member(val name: String) { valnew ArrayBuffer[Network#Member] //以上意思是:“任何Network的Member” }}
Type aliases
For complex types, you can create an alias using the Type keyword.
class Book { import scala.collection.mutable._ type Index = HashMap[String, (Int, Int)] //之后,可以使用Index来代替HashMap了。}
Aliases must be nested within a class or object.
Structure type
The so-called "struct type" refers to a set of specifications for abstract methods, fields, and types. These abstract methods, fields, and types are required to satisfy the type of the specification.
append(str: String): Any}, lines: Iterable[String]) { for(l <- lines){ target.append(1);target.append("\n")}}
You can call the Appendlines method on any instance of the class that has the Append method.
Composite Type
Definition form:
...
Example:
val image = new ArrayBuffer[java.awt.Shape with java.io.Serializable]
with Serializable {def contains(p: Point):Boolean}//该类型的实例必须既是Shape的子类型也是Serializable的子类型。
Middle Type
The middle type is a type with two type parameters.
StringMap Int//String 和 Int类型的中置。//类似数学中的A * B
Existence type
The presence type is added to Scala for compatibility with Java type wildcard characters.
Definition form: After the type expression follows the forsome{...}, the curly braces contain the declarations of type and Val.
fortype T <: JComponent}等价于:Array[_ <: JComponent]
Array[_]等价于:Array[T] forSome{type T}
forSome {typetype U}
Forsome allows us to use more complex relationships, not just those that can be expressed by type wildcard characters.
Map[T, U] forSome {type T; type U <: T}
Scala type System
type |
Syntax Examples |
class or trait |
Class C ..., trait C ... |
Tuple type |
(T1,t2,... Tn) |
function type |
(T1,t2 ... Tn) = = T |
Types with annotations |
[Email protected] |
parameterized types |
A[t1,t2 ... Tn] |
Single Case Type |
Value. Type |
Type projection |
O#i |
Composite type |
T1 with T2 with tn{declaration} |
Middle Type |
T1 A T2 |
Existence type |
T forsome {type and Val declaration} |
Self type
Form:
this类型 =>
Example:
trait Logged { def log(msg: String)}trait LoggedException extends Logged { this: Exception => def log(){log(getMessage())} //可以调用getMessage,因为this是一个Exception}
Dependency Injection
trait LoggerComponent { trait Logger {...} val logger: Logger class FileLogger(file: String) extends Logger {...}}trait Auth { this: LoggerComponent => //让我们可以访问日志器 trait Auth{...} val auth: Auth class MockAuth(file: String) extends Auth {...} ...}
Assembly Accessories:
object AppComponents extends LoggerComponent with AuthComponet { valnew FileLogger(text.log) valnew MockAuth("users.txt")}
Abstract type
A class or trait can define an abstract type that is materialized in a subclass.
trait Reader { type Contents def read(fileName: String): Contents}
Realize:
class StringReader extends Reader { type Contents = String def read(fileName: String) "UTF-8").mkString}class ImageReader extends Reader { type Contents = BufferedImage def read(fileName: String) = ImageIO.read(new File(fileName))}
Another example:
trait Reader[C]{ defRead (file:string): C} class stringreader extends Reader[String] { defRead (filename:string) = Source.fromfile (FileName,"UTF-8"). Mkstring} class imagereader extends Reader[bufferdimage] { defRead (filename:string) = Imageio.read (NewFile (FileName)}
Experience:
1. If the type is given when the class is instantiated, use the type parameter.
2. If the type is given in the subclass, the abstract type is applied.
Advanced Type
The generic type list relies on type T and produces a specific type.
Generic types such as list are sometimes called type constructors.
In Scala, you can define types that depend on types that depend on other types.
Welcome to the Scala discussion QQ group 212859367, and Lianle together to discuss learning!
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Learn scala-with Lianle advanced type