幾次現在我遇到了一個我認爲應該可以通過路徑依賴類型解決的問題,但我不確定我已經能夠執行所以以最完整或正確的方式。在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嗎?我懷疑像無形或宏可能會有所幫助,但如果可能,我想知道是否有可能與路徑依賴類型(或宏確實優先於無形)