Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Внедрить неявные методы/поля в анонимную функцию

Автор вопроса: Bart PlatakОтветов: 1

Я только начинаю работать с Scala и застрял, пытаясь создать один конкретный объект.

У меня есть объект IdentifierFactory, который я хочу использовать для создания экземпляра Identifier. Я определил это так:

object IdentifierFactory {
    def apply(f: => Any):Identifier = {
        f; validate

        Identifier(...)
    }

    def validate:Unit = ???
}

Я хочу иметь возможность использовать его следующим образом:

IdentifierFactory {
    setName("name");
    addResource(resource);
}

Как я могу объявить свои setName и addResource (или, альтернативно, var, к которым у меня есть доступ), чтобы они были видны только в анонимной функции?

  • Не уверен, что означает это последнее предложение. Вы хотите получить доступ к результатам setName и addResource? Если да, не могли бы вы привести пример того, как бы вы их использовали и как validate вступает в игру? Michael Zajac 10.03.2015

scalaimplicit

Ответы

Ответ 1 · рейтинг 2 · dk14

Вы можете передать конструктор в свою анонимную функцию:

IdentifierFactory { b =>
    b.setName("name")
    b.addResource(null)
}

object IdentifierFactory {
    trait Builder {
       def setName(name: String)
       def addResource(r: Any)
    }

    case class Identifier(name: String, rs: List[Any])

    def apply(f: Builder => Any):Identifier = {
        var nm = "default"
        var rs = List[Any]()
        f(new Builder {
           def setName(name: String) = nm = name
           def addResource(r: Any) = rs ::= r
        })
        validate

        Identifier(nm, rs)
    }

    def validate: Unit = {}
}

scala> IdentifierFactory { b =>
 |         b.setName("name")
 |         b.addResource(null)
 |     }
res4: IdentifierFactory.Identifier = Identifier(name,List(null))

Кстати, вы все еще можете сделать то же самое, просто передав имя и список ресурсов в функцию со значениями по умолчанию:

object IdentifierFactory {
    case class Identifier(name: String, rs: List[Any])

    def apply(nm: String = "default", rs: List[Any] = List[Any]()): Identifier = {
        //validate it right here
        Identifier(nm, rs)
    }

}

scala> IdentifierFactory()
res7: IdentifierFactory.Identifier = Identifier(default,List())

scala> IdentifierFactory(rs = List(null))
res8: IdentifierFactory.Identifier = Identifier(default,List(null))

scala> IdentifierFactory("nm", List(null))
res9: IdentifierFactory.Identifier = Identifier(nm,List(null))

scala> IdentifierFactory("nm")
res10: IdentifierFactory.Identifier = Identifier(nm,List())

Я бы также рекомендовал возвращать Option или Either вместо исключения проверки.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы