2016-06-05 7 views
1

У меня есть следующий класс:Исключение нулевого указателя работы с Map (Котлин)

class SymbolTable(){ 
    var map = mutableMapOf<String, Entry>() 
    var kindCounter = mutableMapOf<String, Int>() 

    fun define(name:String, kind:String, type:String){ 
     if(kindCounter[kind]==0){ 
      kindCounter[kind]=0 
     } 
     var index = 1 
     map[name]= Entry(type, kind, index) 
     kindCounter[kind]=kindCounter[kind]!!.plus(1) 
    } 

Начальный класс выглядит следующим образом:

class Entry(var type:String, var kind:String, var index:Int) 

Main:

fun main(args:Array<String>){ 
    var example = SymbolTable() 
    example.define("ex1", "ex1", "ex1") 
    example.define("ex2", "ex2", "ex2") 
} 

Когда я бегу в программе и попробуйте использовать функцию «define». Я получаю следующую ошибку:

Exception in thread "main" kotlin.KotlinNullPointerException 
    at SymbolTable.define(SymbolTable.kt:21) 
    at SymbolTableKt.main(SymbolTable.kt:31) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 

Я предполагаю, что проблема связана с тем, как я создаю новый класс symbolTable, но, видя, что у Kotlin нет «нового», я не знаю, как избежать исключения нулевого указателя.

+0

Пожалуйста, не редактируйте ваш вопрос таким образом, что он аннулирует существующие ответы. Вместо этого опубликуйте новый вопрос. – Matt

ответ

2
if(kindCounter[kind]==0){ 
    kindCounter[kind]=0 
} 

Это не имеет особого смысла: вы проверить, если значение равно 0, и если вы установите его в 0. Таким образом, это в основном Нооп.

Что вы хотите, чтобы проверить, если значение равно нулю:

if (kindCounter[kind] == null) { 
    kindCounter[kind] = 0 
} 

Можно также избежать использования опасного !! оператора, сохранив значение в переменную.

И вы действительно должны использовать Вэла вместо вар: все ваши поля не должно быть изменяемым:

class SymbolTable() { 
    val map = mutableMapOf<String, Entry>() 
    val kindCounter = mutableMapOf<String, Int>() 

    fun define(name: String, kind: String, type: String) { 
     val count = kindCounter[kind] ?: 0 
     map[name] = Entry(type, kind, 1) 
     kindCounter[kind] = count + 1 
    } 
} 

class Entry(val type: String, val kind: String, val index: Int) 

fun main(args:Array<String>) { 
    val example = SymbolTable() 
    example.define("ex1", "ex1", "ex1") 
    example.define("ex2", "ex2", "ex2") 
} 
+0

Это может быть глупый вопрос, но я думал, что val не может быть изменен после назначения, и мне нужно изменить мою карту в этой программе. –

+0

Вам необходимо изменить ** содержимое ** карты. Вы можете это сделать, потому что карта имеет тип MutableMap. Но вам не нужно заменять карту другим, т. Е. Назначать новое значение переменной карты, т. Е. Делать 'map = anotherMap'. –