2017-11-05 2 views
6

私はAnko SQLiteのドキュメントを読んでいます。Ankoの簡単なMapRowParserとは何ですか?

私は、単純なRowParserの器IScanを作成classParserはアンコ - SQLiteのソースコードで定義された関数であるval rowParser = classParser<Person>()

を行うことによって行われることを知っています。

どうすれば簡単にMapRowParserを取得できますか?

+0

https://stackoverflow.com/a/47076693/9204を参照してください。 –

+0

ありがとうございます。AnkoはclassParserと同じようにあらかじめ定義されたMapRowParserを持っていませんか?私はMapRowParserを自分で書く必要がありますか? – HelloCW

答えて

3

Githubにアクセスしてthis searchを実行すると、MapRowParserが参照されるファイルが2つあることがわかります。

最初のファイルには、これを含んでいます

interface MapRowParser<out T> { 
    fun parseRow(columns: Map<String, Any?>): T 
} 

インタフェースとしてMapRowParserを示しています。

ただし、検索によると、MapRowParserが言及されている2つのファイルがあります。ファイルを調べると、クラスがないことがわかります。クラスの手動実装を示すthis questionによれば、それは手動で実装されなければならない。また、Ankoのコードでは、MapRowParserを実装するクラスは表示されません。

したがって、MapRowParserを独自に実装するクラスを作成する必要があります。ドキュメントとコードを正しく読んだら、マップ自体は自動的に渡されますが、パーサーは受信したデータを処理します。


RowParserと同等です。それはインターフェイスです。しかし、there is a method that returns a specific parser。しかし、RowMapParserのようなものはありません。

EDIT:the source codeに入る

は、単一の行パーサの2種類がいくつかの異なるタイプのために使用されていることを示しています。 MapRowParserが存在しないのは、一般的なマップパーサーを作成するのが難しいからです。彼らは、キーと値を持っているようにリストが唯一あなたがタイプと戻りとしてキャスト値を有している地図は、一般的に異なる動作を持っている:

private class SingleColumnParser<out T> : RowParser<T> { 
    override fun parseRow(columns: Array<Any?>): T { 
     if (columns.size != 1) 
      throw SQLiteException("Invalid row: row for SingleColumnParser must contain exactly one column") 
     @Suppress("UNCHECKED_CAST") 
     return columns[0] as T//Right here it just casts the column as the type defined when creating 
    } 
} 

あなたは地図と同じことを行うことができますが、キーは希望失われます。さらに、ソースコードを調べると、パーサーに渡されたデータには1つの列しか含まれていないことがわかります。ビットさらにソースに食い込む

はまた、この方法を明らかにする:

private fun readColumnsMap(cursor: Cursor): Map<String, Any?> { 
    val count = cursor.columnCount 
    val map = hashMapOf<String, Any?>() 
    for (i in 0..(count - 1)) { 
     map.put(cursor.getColumnName(i), cursor.getColumnValue(i)) 
    } 
    return map 
} 

Iは、ソースの権利を読んでいる場合は、上記の方法は、単一のマップに行全体を変換し、列の名前を取りそれと。だから、単一行のためにこのようなもので終わる:

Col1 -> Row1col1val 
Col2 -> Row1col2val 
... 
システムが一覧に複数のエントリを解析する方法で見ることができますカーソル、または地図上で稼働

moveToFirst() 
while (!isAfterLast) { 
    list.add(parser.parseRow(readColumnsMap(this)))//adds the result into a pre-defined list to return 
    moveToNext() 
} 

また、戻り値が必要であるため、ジェネリックの作成は難しいことを示しています。単一の戻り値に入れるデータの種類がわからない場合は、やりにくいです。

これは、一般的なパーサを書くのは難しいです。行の量や値の処理などは決して分からないからです。したがって、独自のパーサを書くためにMapRowParserを実装するクラスを作成し、これを使用して必要なデータを解析します。インスタンスの場合は、BLOBとして格納されたクラスにIDを割り当て、それを使用するデータクラスにデータを入れます。

*開発者がどのようにデータを必要とするかわからないため、書くのは難しいです。あなたがマップとして持っている場合、他のすべてのデータが失われるので、ただ一つの値を返すことはできません。 したがって、一般的なパーサに必要な場合はマップとして戻す必要があり、開発者はデータを解析する必要があります。リストを使用すると、単一の値を返すだけで簡単です。しかし、Mapでは、データを失わないために、標準化された目的のために書かれていれば、本質的に役に立たなくなります。

+0

ありがとう!なぜAnkoはclassParserを書くのですか?なぜAnkoはMapRowParserの実装を書いていないのですか?私はそれが非常に奇妙だと感じる! – HelloCW

+0

なぜ彼らはそれを実装していないのか分かりません。それは一般的な使用のために実装するにはあまりにも複雑な型である可能性があります。あなたはそれに正確な答えが必要な場合は、クリエイターに尋ねる必要があります。 – Zoe

+0

@HelloCWはコードを掘り下げて答えを編集しました。 – Zoe

関連する問題