У меня есть эта функция kotlin, которую я использую для доступа к данным после выполнения http-запроса с использованием библиотеки fuel в Android, из учебника, которому я следую, но некоторые части этой функции для меня странны, поскольку я изучаю kotlin:
fun search(term: String, skip: Int, take: Int, responseHandler: (result: WikiResult) -> Unit?) {
Urls.getSearchUrl(term, skip, take).httpGet()
.responseObject(WikipediaDataDeserializer()) { _, response, result ->
if (response.statusCode != 200) {
throw Exception("Unable to get articles")
}
val(data, _) = result
responseHandler.invoke(data as @ParameterName(name = "result") WikiResult)
}
}
Это я понимаю до сих пор:
responseHandler: (result: WikiResult) -> Unit?: анонимная функция, которая ничего не возвращаетно я не могу понять большую часть этой части:
.responseObject(WikipediaDataDeserializer()) { _, response, result ->
if (response.statusCode != 200) {
throw Exception("Unable to get articles")
} #<-- this I know throws an exception if the response isn't a 200
val(data, _) = result
responseHandler.invoke(data as @ParameterName(name = "result") WikiResult)
}
responseHandler: (result: WikiResult) -> Unit? — это функция обратного вызова (лямбда).
В нем говорится, что он примет result: WikiResult и передаст его тому, кто его вызывает.
.responseObject(WikipediaDataDeserializer()) { _, response, result ->
if (response.statusCode != 200) {
throw Exception("Unable to get articles")
} #<-- this I know throws an exception if the response isn't a 200
val(data, _) = result
responseHandler.invoke(data as @ParameterName(name = "result") WikiResult)
}
здесь, где вы вызываете responseObject(WikipediaDataDeserializer()), вы указываете, как обрабатывать другую лямбда-функцию.
{ _, response, result -> просто говорит, что вы получаете 3 значения, первое вам не нужно, вы его не используете, поэтому вы можете переименовать его в _, затем ваш объект response и ваш объект result, который вы будете использовать, поэтому им были даны эти имена соответственно.
Редактировать
вы должны смотреть на это как на 2 разных метода:
когда вы позвоните search, вы сделаете это:
search("term", 0, 0) {
//this is your responseHandler: (result: WikiResult) -> Unit?)
// in here, you'll get a result: WikiResult
}
аналогично, когда вы вызываете это:
Urls.getSearchUrl(term, skip, take).httpGet()
.responseObject(WikipediaDataDeserializer()) { _, response, result -> ...
вся эта цепочка имеет обратный вызов, который вы возвращаете, и он дает вам 3 значения, как объяснено в моем ответе выше.
val(data, _) = result известен как Destructuring Declarationshttps://kotlinlang.org/docs/reference/multi-declarations.html
но да, вы правы в своем понимании, мы используем ответ этого обратного вызова, уничтожаем его, а затем запускаем обратный вызов с этими данными
Позвольте мне посмотреть, понимаю ли я вас, поэтому в конце WikiResult будет передан WikipediaDataDeserializer(), чтобы преобразовать его в формат json?
Вот WikiResult быть data после кастинга!
на самом деле, вы тоже правы, responseHandler.invoke вызывает обратный вызов
Да, kotlin настолько плавный, что его синтаксис почти похож на javascript!
собираюсь перенести это в чат
Давайте продолжить обсуждение в чате.
Может помочь: Функции высшего порядка и лямбда-выражения и Разрушение объявлений.