Пару раз сейчас я столкнулся с проблемой, которая, по моему мнению, должна быть разрешимой для зависимых от пути типов, но я не уверен, что мне удалось это сделать поэтому самым полным или правильным способом. В мире Java нередко есть перечисление (или чаще всего псевдо-перечисление в виде кучи статических значений), которые определяют замкнутый набор, который сопоставляется с родными типами. java.sql.Types
является хорошим примером:Scala для переходов на собственные типы с зависимыми от пути типами
public class Types {
/**
* <P>The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* <code>BIT</code>.
*/
public final static int BIT = -7;
/**
* <P>The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* <code>TINYINT</code>.
*/
public final static int TINYINT = -6;
/**
* <P>The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* <code>SMALLINT</code>.
*/
public final static int SMALLINT = 5;
// ...
}
Я хотел бы, чтобы обеспечить некоторое отображение, что возьмет меня от этих перечислений до их собственных типов. До сих пор у меня есть что-то вроде этого:
import java.sql.{Types, ResultSet}
trait SqlType {
def typeValue:Int
type Value
def getValue(rs:ResultSet, idx:Int):Value
}
object SqlType {
object SqlInt extends SqlType {
type Value = Int
def typeValue = Types.INTEGER
def getValue(rs:ResultSet, idx:Int) = rs.getInt(idx)
}
object SqlString extends SqlType {
type Value = String
def typeValue = Types.NVARCHAR
def getValue(rs:ResultSet, idx:Int) = rs.getString(idx)
}
def getSqlType(typeValue:Int):SqlType = typeValue match {
case Types.INTEGER => SqlInt
case Types.NVARCHAR => SqlString
}
implicit class ResultSetExtras(rs:ResultSet) {
def getCell(idx:Int, sqlType:SqlType):sqlType.Value = sqlType.getValue(rs, idx)
}
}
Это немного шаткий, однако, как мне нужно, чтобы получить конкретный SqlType
экземпляр, прежде чем руки и передать его в качестве аргумента функции, чтобы получить правильный путь в зависимости от тип. Так что это не кажется, что я могу сделать что-то вроде этого, что то, что я действительно люблю:.
implicit class ResultSetExtras2(rs:ResultSet) {
def getCell2(idx:Int):SqlType#Value = getSqlType(rs.getMetaData.getColumnType(idx)).getValue(rs, idx)
}
(обратите внимание на тип возвращаемого SqlType#Value
, а не зависимые от пути sqlType.Value
Есть ли (лучше), чтобы достичь этого в чистом scala? Я подозреваю, что что-то вроде бесформенных или макросов может помочь, но, если возможно, я хотел бы знать, возможно ли это с зависимыми от пути типами (или макросами действительно предпочтение бесформенному).