2016-11-04 66 views
1

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

回答

1

問題在於編譯時不可能在編譯時間處爲rs.getCell(2)知道具體的數值類型將產生什麼樣的路徑相關的t ypes在這裏沒有幫助。結果的類型只能在運行時上知道。如果您選擇抽象類型SqlType作爲返回值(這與java的情況相同),那麼這不是問題。您無法獲得由SqlType#Value代表的實際類型。