Реализация интерфейсов в Котлине - PullRequest
0 голосов
/ 18 октября 2018

Может ли кто-нибудь объяснить мне синтаксис этой реализации интерфейса?Почему мне нужно использовать знак '=' для реализации CommandLineRunner.Когда я использую знак «:» (в соответствии с основным синтаксисом http://kotlinlang.org/docs/reference/interfaces.html) компилятор требует оператора возврата.

@SpringBootApplication 
 class Application{

@Bean
fun imageProcess(repo: MongoRepository) = CommandLineRunner {      
   val room2 = Room(id ="1AN1",
                    primaryUnit = "XYZ")
    repo.save(room)}}

@FunctionalInterface
public interface CommandLineRunner {
void run(String... args) throws Exception;}

1 Ответ

0 голосов
/ 18 октября 2018

Хорошо, если предположить, что это компилируется (что не ясно, потому что вы пропустили тело функции), тогда верно следующее:

imageProcess возвращает CommandLineRunner.Вы можете опустить фигурные скобки вокруг функционального блока и просто использовать функцию выражения выражения, как здесь.

Функция тела выражения - это функция, тело которой является выражением (где выражение является блоком кода, который разрешается до значения определенного типа).

https://kotlinlang.org/docs/reference/lambdas.html

Возьмем их в качестве примеров:

// 1 + 2 + 3 is an expression that resolves to an Integer value. 
// Therefore, the return type is Int
fun intExpression() = 1 + 2 + 3

// false && true is an expression that resolves to a Boolean value.
// Therefore, the return type is Boolean
fun boolExpression() = false && true

// The when here is a fully exhaustive when expression
// It can resolve to an Integer or a String. 
// Therefore the return type is the common subtype of both
// Integer and String which happens to be Any (the root of the Kotlin type heirarchy.
fun anyExpression(foo: Boolean) = when(foo) {
    true -> 1
    else -> "Hello"
} 

Более формальное определение выражения:

https://blog.kotlin -academy.com / kotlin-programmer-dictionary-Statement-vs-expression-e6743ba1aaa0

РЕДАКТИРОВАТЬ 1:

Чтобы пояснить далее, на самом деле происходит создание анонимной реализации интерфейса CommandLineRunner.Это может быть написано только так, как вы написали, потому что интерфейс определяет один абстрактный метод.Это означает, что ваш CommandLineRunner интерфейс имеет тип SAM, а компилятор выполняет преобразование типа SAM.Другими словами, вы могли бы написать свой код следующим образом:

class MyCommandLineRunner(repo: MongoRepository) : CommandLineRunner {
   override fun run(args: String) {
        // Do stuff...
   }
}

fun imageProcess(repo: MongoRepository) = MyCommandLineRunner(repo)

Но вам не нужно этого делать, потому что интерфейс имеет единственный абстрактный метод, так что вы можете просто определить встроенную реализациюинтерфейс без необходимости явного переопределения функции run.

Подробнее о типах SAM и преобразовании SAM здесь:

https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions

EDIT 2:

Наконец, посмотрите здесь:

https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/CommandLineRunner.html

Это интерфейс, который вы реализуете.Как видите, он соответствует определению типа SAM, поэтому вы можете создать его встроенную реализацию без явного указания переопределения функции run.Если бы в интерфейсе был дополнительный метод (скажем, stop), вам пришлось бы написать свою анонимную реализацию следующим образом:

@Bean
fun imageProcess(repo: MongoRepository) = object : CommandLineRunner {
   override fun run(args: String) {
      // Do stuff
   }

   override fun stop() {
      // Do stuff
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...