Search code examples
scalaif-statement

found Unit: required [Something Else]


My code is:

   var storage: Storage =
    if (config.storageType == StorageType.MAP)
      MapStorage()
    else if (config.storageType == StorageType.LIST)
      ListStorage()
    else ()

The error I am receiving is

[E007] Type Mismatch Error
Found:    Unit                                                                                                                                                     
Required: ****.utils.Storage 

*** is just placed to omit the actual value. I know that there is no stand-alone if statement in scala and hence the last else() statement is present in the code.


Solution

  • You can't return () having type Unit if you promised to return Storage (storage: Storage).

    Either return a Storage

    val storage: Storage =
      if (config.storageType == StorageType.MAP)
        MapStorage()
      else if (config.storageType == StorageType.LIST)
        ListStorage()
      else MapStorage() // or ListStorage() or some other storage
    

    or make one of the cases default

    val storage: Storage =
      if (config.storageType == StorageType.MAP)
        MapStorage()
      else // default case
        ListStorage()
    

    or if you really can't return any of storages in the default case, return null (it's worse since this can lead to NullPointerException in the code for unknown reason)

    val storage: Storage =
      if (config.storageType == StorageType.MAP)
        MapStorage()
      else if (config.storageType == StorageType.LIST)
        ListStorage()
      else null 
    
    // null has type `Null`, which is a subtype of any reference type, e.g. Storage
    // Null <: Storage
    // Null | Storage =:= Storage
    

    or throw exception with a proper message (it's better than returning null)

    val storage: Storage =
      if (config.storageType == StorageType.MAP)
        MapStorage()
      else if (config.storageType == StorageType.LIST)
        ListStorage()
      else throw new RuntimeException("unexpected storage type")
    
    // throwing exception has type Nothing, which is a subtype of any type, e.g. Storage
    // Nothing <: Null <: Storage
    // Nothing | Storage =:= Storage
    

    or change signature to Option (it's even better than throwing but you'll probably have to fix also places where storage is used)

    val storage: Option[Storage] =
      if (config.storageType == StorageType.MAP)
        Some(MapStorage())
      else if (config.storageType == StorageType.LIST)
        Some(ListStorage())
      else None
    

    Technically, you can return union type Unit | Storage in Scala 3 (or its emulation in Scala 2) but such signature would be weird.