这是预期的行为吗?
scala> val l: List[Void] = "I'm void".asInstanceOf[String with Void] :: Nil
l: List[Void] = List(I'm void)
将l
识别为List[Void]
并将String
显示为第一个元素是否有效?
答案 0 :(得分:2)
从某种意义上说,这是完全有效的,并不是class ProfilesController < ApplicationController
before_action :authenticate_user!, except: [:show]
before_action :find_profile_by_id, only: [:show, :edit, :update]
after_filter :destroy_user!, only: [:destroy]
def index
if @profile.blank?
render :new
else
render :show
end
end
def new
@profile = current_user.profiles.build
@user = current_user.where('email=?')
end
def create
@profile = current_user.profiles.build(profile_params)
if @profile.save
redirect_to @profile
else
render :new
end
end
def show
end
def edit
end
def update
if @profile.update(profile_params)
redirect_to @profile
else
render :edit
end
end
def destroy
@user.destroy
@profile.destroy
redirect_to root_path
end
private
def profile_params
params.require(:profile).permit(:name, :email, :bio, :location, :homepage, :work)
end
def find_profile_by_id
@profile = Profile.find(params[:id])
end
def destroy_user!
@user = User.find(params[:id])
end
end
特有的。单独Void
"I'm void".asInstanceOf[String with Void]
这是有效的,因为我们要求编译器说ClassCastException
是val l: List[Void] = "I'm void".asInstanceOf[String with Void] :: Nil
的实例,而"I'm void"
是String with Void
的子类型},这意味着我们可以片刻有一个String with Void
,因为Void
。 然而,如果我们尝试访问List[Void]
的头部,我们预计会有List[String with Void] <: List[Void]
,原来的List[Void]
不是。{/ p>
Void
它似乎首先起作用,因为所有内容都有String
方法,因此不需要将其视为scala> l.head
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Void
以外的其他内容。
如果我们使用toString
进行尝试,也会发生同样的事情。
Any
String with Int
将很高兴存在,直到现实开始,我们才意识到它实际上不是scala> val int = "I'm an Int".asInstanceOf[String with Int]
int: String with Int = I'm an Int
scala> int % 2
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
,并且没有String with Int
方法。< / p>
答案 1 :(得分:2)
稍微扩展@ m-z的答案,解释为什么 .asInstanceOf[String with Void]
不会抛出。我们需要区分Scala中存在的内容以及JVM字节码中存在的内容。特别是,字节码不支持像String with Void
这样的交集类型,因此无法转换为它。因此,为.asInstanceOf[String with Void]
发出的字节码实际上与.asInstanceOf[String]
相同;但是当编译器看到此类型的值用作Void
时,它会插入额外的强制转换。
这就是为什么你不能使用List[Int]
区分具有不同参数的通用类型(如List[String]
和isInstanceOf
)的原因:就字节码而言,类型是相同的。