2017-05-03 2 views
0

Dies ist mein Code:nicht Zeichen in scala entsprechen kann, Referat erwartet Typ

val foo = "\\foo" 
var escaped = "" 
foo.foreach(c => { 
    escaped += c match { 
    case '_' => "\\_" 
    case '\\' => "\\textbackslash{}" 
    case '~' => "\\textasciitilde{}" 
    case '^' => "\\textasciicircum{}" 
    case '&' => "\\&" 
    case '%' => "\\%" 
    case '#' => "\\#" 
    case '{' => "\\{" 
    case '}' => "\\}" 
    case ch => ch 
    } 
}) 

IntelliJ sagt mir, dass Muster Typ mit erwarteten Typ nicht kompatibel ist, gefunden: Char, erforderlich: Einheit. Warum passiert das? c ist offensichtlich ein Char, keine Einheit.

Antwort

2

Das Problem, um es von Anhängen sind Sie passen zu '_' usw. Sie match innen () dann Concat mit einer anderen Variablen.

val foo = "\\foo" 
var escaped = "" 

foo.foreach((char : Char) => { 
    escaped = escaped + (char match { 
    case '_' => "\\_" 
    case '\\' => "\\textbackslash{}" 
    case '~' => "\\textasciitilde{}" 
    case '^' => "\\textasciicircum{}" 
    case '&' => "\\&" 
    case '%' => "\\%" 
    case '#' => "\\#" 
    case '{' => "\\{" 
    case '}' => "\\}" 
    case ch => ch 
    }) 
}) 

println(escaped) //prints \textbackslash{}foo 
2

Nun ... die Sache ist, dass foreach auf einem collection type wie List[A] folgende Signatur hat,

foreach(func: A => Unit): Unit 

was bedeutet, dass foreach eine Funktion vom Typ A => Unit als Parameter will.

In diesem Fall haben Sie eine String, und hier foreach will eine Funktion des Typs Char => Unit als Parameter.

Aber Blick auf den Körper Ihrer Funktion ...

c => { 
    escaped += c match { 
    case '_' => ... 
    ... 
    } 
} 

Was Sie eigentlich hier ist haben,

c => { 
    (escaped += c) match { 
    case '_' => ... 
    ... 
    } 
} 

Und (escaped += c) ist Unit. So lösen dies alles, was Sie zu verwenden sind richtige Klammer,

c => { 
    escaped += (c match { 
    case '_' => ... 
    ... 
    }) 
} 

Auch ... Sie sollten es vermeiden, mit diesem Ansatz für diesen String zu bauen. Sie können nur ein map benutzen, um Ihren String zu erstellen, anstatt in einem foreach

val foo = "\\foo" 
val escaped = foo.map(c => c match { 
    case '_' => "\\_" 
    case '\\' => "\\textbackslash{}" 
    case '~' => "\\textasciitilde{}" 
    case '^' => "\\textasciicircum{}" 
    case '&' => "\\&" 
    case '%' => "\\%" 
    case '#' => "\\#" 
    case '{' => "\\{" 
    case '}' => "\\}" 
    case ch => "" + ch 
}).mkString