2016-09-19 8 views
2

私は理解していないことを経験しています。私が理解していることは、「this」は生きているオブジェクトではnullにはなりませんが、以下に示すケースでは、私はそのようなことを経験しています。Scala - ライブオブジェクトのScalaでthis thisがnullになることはありますか?

コンテキスト - このケースではXGBoost4J-Sparkパッケージを使用しています。ソースコードhereを見ることができます。具体的には、XGBoostEstimatorクラスを参照しています。私はクラスの次の定義を持っています。追加のprint文が1つだけあります。

package ml.dmlc.xgboost4j.scala.spark 

import ml.dmlc.xgboost4j.scala.{EvalTrait, ObjectiveTrait} 
import org.apache.spark.ml.{Predictor, Estimator} 
import org.apache.spark.ml.param.ParamMap 
import org.apache.spark.ml.util.Identifiable 
import org.apache.spark.mllib.linalg.{VectorUDT, Vector} 
import org.apache.spark.mllib.regression.LabeledPoint 
import org.apache.spark.sql.functions._ 
import org.apache.spark.sql.types.{NumericType, DoubleType, StructType} 
import org.apache.spark.sql.{DataFrame, TypedColumn, Dataset, Row} 

/** 
* the estimator wrapping XGBoost to produce a training model 
* 
* @param inputCol the name of input column 
* @param labelCol the name of label column 
* @param xgboostParams the parameters configuring XGBoost 
* @param round the number of iterations to train 
* @param nWorkers the total number of workers of xgboost 
* @param obj the customized objective function, default to be null and using the default in model 
* @param eval the customized eval function, default to be null and using the default in model 
* @param useExternalMemory whether to use external memory when training 
* @param missing the value taken as missing 
*/ 
class XGBoostEstimator(
    inputCol: String, labelCol: String, 
    xgboostParams: Map[String, Any], round: Int, nWorkers: Int, 
    obj: Option[ObjectiveTrait] = None, 
    eval: Option[EvalTrait] = None, useExternalMemory: Boolean = false, missing: Float = Float.NaN) 
    extends Estimator[XGBoostModel] { 

    println(s"This is ${this}") 
    override val uid: String = Identifiable.randomUID("XGBoostEstimator") 


    /** 
    * produce a XGBoostModel by fitting the given dataset 
    */ 
    def fit(trainingSet: Dataset[_]): XGBoostModel = { 
    val instances = trainingSet.select(
     col(inputCol), col(labelCol).cast(DoubleType)).rdd.map { 
     case Row(feature: Vector, label: Double) => 
     LabeledPoint(label, feature) 
    } 
    transformSchema(trainingSet.schema, logging = true) 
    val trainedModel = XGBoost.trainWithRDD(instances, xgboostParams, round, nWorkers, obj.get, 
     eval.get, useExternalMemory, missing).setParent(this) 
    copyValues(trainedModel) 
    } 

    override def copy(extra: ParamMap): Estimator[XGBoostModel] = { 
    defaultCopy(extra) 
    } 

    override def transformSchema(schema: StructType): StructType = { 
    // check input type, for now we only support vectorUDT as the input feature type 
    val inputType = schema(inputCol).dataType 
    require(inputType.equals(new VectorUDT), s"the type of input column $inputCol has to VectorUDT") 
    // check label Type, 
    val labelType = schema(labelCol).dataType 
    require(labelType.isInstanceOf[NumericType], s"the type of label column $labelCol has to" + 
     s" be NumericType") 
    schema 
    } 
} 

私は次、Sprak・シェル(またはその他のテストを介して)を通じて同じコードを初期化し、私が得る出力されます:

scala> import ml.dmlc.xgboost4j.scala.spark.XGBoostEstimator 
import ml.dmlc.xgboost4j.scala.spark.XGBoostEstimator 

scala> val xgb = new XGBoostEstimator("features", "label", Map.empty,10, 2) 
This is null 
xgb: ml.dmlc.xgboost4j.scala.spark.XGBoostEstimator = XGBoostEstimator_6cd31d495c8f 

scala> xgb.uid 
res1: String = XGBoostEstimator_6cd31d495c8f 

理由とするとき、この動作が可能である上の任意の明確化助けになるだろう。

+0

は、あなたはそれが '' this.toString() '文字列を返す' "ヌル" ではないのですか?代わりに 'println(" null? "+(this eq null))'を印刷するとどうなりますか? – sjrd

+0

@sjrd私はtoStringが基本クラスでオーバーライドされていることを見落としました。あなたが正しいです、それは問題を引き起こしたtoStringでした。 –

答えて

6

toString()の実装は、Identifiableから提供され、これは単にuidセットを返します。そして、次の行にuidを設定するので、印刷時に初期化されません。

を特定できるsource

trait Identifiable { 

    /** 
    * An immutable unique ID for the object and its derivatives. 
    */ 
    val uid: String 

    override def toString: String = uid 
} 
関連する問題