Option
s не Java s @nullable
s. Вы сопоставляете шаблон на Some
, если присутствует значение:
val obj = FileSystem("test.properties") // Option[FileSystem]
obj match {
case Some(test) => test.moveFile("test.properties")
case None =>
}
Также в Scala почти все является выражением, поэтому if-else
, блоки, циклы и функции возвращают свое последнее значение как значение всех , Также мы должны принимать во внимание ошибки ввода-вывода, поэтому Try
может быть лучше, чем Option
:
def apply(propFileURI: String): Try[FileSystem] =
Try {
// reading properties could fail
val p = new Properties()
val source = Source.fromFile( System.getProperty("user.dir")+"\\src\\main\\resources\\"+propFileURI).reader
p.load(source)
p
}.flatMap { properties =>
// reading from properties could fail
val srcPath = properties.getProperty("srcPath")
val destPath = properties.getProperty("destPath")
if (destPath.contains("hdfs")) Success(new HDFSystem())
else if (srcPath.contains("s3") && destPath.contains("s3")) Success(new S3System())
else Failure(new Exception("Unable to recognize filesystem"))
}
def main(args: Array[String]): Unit =
FileSystem("test.properties") match {
case Success(fileSystem) => fileSystem.moveFile("test.properties")
case Failure(error) => error.printStackTrace()
}
Мы можем в любой момент преобразовать Try
в Option
с .toOption
и pattern- совпадать на нем. Но таким образом у нас нет информации об ошибке. Мы также можем создать тип FileSystemError
для хранения информации об ошибках и вернуть Either[FileSystemError, FileSystem]
вместо Try
. Наконец, мы могли бы просто выбросить Exception
, но таким образом мы возвращаемся к Java -подобным практикам, которые не говорят нам, что ошибка может произойти, и это удивляет нас во время выполнения.
Что я, несомненно, хотел бы do - переименовать apply
- обычно мы ожидаем, что объект apply всегда будет возвращать успех, поэтому, если это невозможно, и мы используем какой-то умный конструктор, мы должны дать ему другое имя. Например, здесь мы могли бы назвать его
def resolveFor(propFileURI: String): Either[FileSystemError, FileSystem] = ...
, чтобы каждый, кто использовал его, знал, какое поведение ожидать только от подписи.