2015-01-14 15 views
7

Trong mã Scala của tôi, tôi có một số chuyển đổi ngầm, và tôi có nhập khẩu cần thiết hiện nay:Tại sao lại cảnh báo khi scala.language.implicitConversions không phải là lần nhập cuối cùng?

import scala.language.implicitConversions 

Tuy nhiên, đôi khi có một nhập khẩu thực hiện sau khi thế này, tôi nhận được cảnh báo là nếu việc nhập khẩu là không có ở tất cả:

Cảnh báo: (112, 18) ngầm chuyển đổi phương pháp pair2Dimension nên được kích hoạt bằng cách làm cho scala.language.implicitConversions giá trị tiềm ẩn có thể nhìn thấy.

build.sbt:

name := "ImplicitSBT" 

version := "1.0" 

scalaVersion := "2.11.5" 

scalacOptions ++= Seq("-deprecation","-feature") 

libraryDependencies += "org.scala-lang.modules" %% "scala-swing" % "1.0.1" 

Main.scala:

import scala.language.implicitConversions 
import scala.swing.{Action, _} 

object Main extends App { 

    implicit def pair2Dimension(pair: (Int, Int)): Dimension = new Dimension(pair._1, pair._2) 

    val dim : Dimension = (0,0) 

    println(dim) 


} 

Tại sao điều này xảy ra? Làm thế nào là import scala.swing.{Action, _} ẩn nhập implicitConversions?

Trả lời

4

Nhập scala.swing. {Action, _} ẩn nhập khẩu Chuyển đổi nội dung ngầm?

của bạn:

import scala.language.implicitConversions 

... bị lu mờ bởi implicitConversionsdefined trong đối tượng scala.swing gói:

package scala 

... 

package object swing { 

... 

implicit lazy val implicitConversions = scala.language.implicitConversions 

... 

} 

Vì bạn đang sử dụng nhập khẩu ký tự đại diện ở đây:

import scala.swing.{Action, _} 

... scala.swing.implicitConversions được nhập khẩu từ scala.swing và trong bóng tối cuối scala.language.implicitConversions.

Câu hỏi thú vị là: tại sao scalac không tìm ra tính năng ngôn ngữ được bật nếu có hai "cờ tính năng" (implicitConversions trong trường hợp này), một cái khác ở cùng cấp.

Đây có thể là một lỗi cũng như chi tiết cụ thể về cách SIP 18 được thực hiện.

Dù sao, để giải quyết việc này tôi có thể đề nghị bạn làm một trong các cách sau:

  1. không nhập scala.language.implicitConversions (vì nó đã được nhập khẩu khi ký tự đại diện nhập khẩu scala.swing)

  2. không làm nhập ký tự đại diện từ scala.swing (không gây ô nhiễm phạm vi của bạn và nhập khẩu những gì bạn cần thay thế)

  3. thực hiện một lần nhập khác (không bị bóng khác) implicitConversions tại mức độ đối tượng Main

+0

Để được rõ ràng: câu hỏi thú vị không phải là lý do tại sao hai va chạm (đó là dự kiến), nhưng tại sao họ không khi nhập khẩu 'scala.language' đến thứ hai. –

+0

@Travis Tôi nghĩ rằng một nhập (một tên) cụ thể đã được ưu tiên hơn việc nhập ký tự đại diện được thực hiện trước đó. – Suma

+0

@Suma oh, đúng, có ý nghĩa. Vì vậy, điều này không quá bí ẩn chút nào. –

1

Đây là lỗi trong tra cứu tiềm ẩn.

Đây là cấu trúc giống với mã bình thường hơn, trong đó ngầm định bắt buộc là bối cảnh thực thi.

(Nó không quan trọng cho dù việc nhập khẩu wildcard là từ một đối tượng gói, hoặc cho dù các gói còn lại là ở các đơn vị biên soạn cùng.)

Kể từ khi mã biên dịch với một rõ ràng global, cần biên dịch với một arg tiềm ẩn.

Ẩn tiềm ẩn nếu có thể là accessed without a prefix.

binding precedence không bị ảnh hưởng bởi thứ tự mã nguồn. Shadowing hoạt động theo cách thông thường; một ràng buộc không bao giờ che một ràng buộc của ưu tiên cao hơn.

/* 
package object bound2 { 
    implicit lazy val global = scala.concurrent.ExecutionContext.Implicits.global 
} 
*/ 
package bound2 { 
    object B { 
    implicit lazy val global: concurrent.ExecutionContextExecutor = scala.concurrent.ExecutionContext.global 
    } 
} 

package bound { 
    // the order of these imports in the same scope should not matter 
    import scala.concurrent.ExecutionContext.Implicits.global 
    import bound2.B._ 

    object Test extends App { 
    val f = concurrent.Future(42) //(global) // explicit arg works 
    Console println concurrent.Await.result(f, concurrent.duration.Duration.Inf) 
    } 
} 

Trong ví dụ đặc tả 2.0.1, thêm dòng được đánh dấu "OK" biên dịch, và bạn có thể xác minh rằng đơn không quan trọng, nhưng nó trở nên mơ hồ trong phạm vi nội vì "wildcard y" có không bóng "y rõ ràng" từ phạm vi bên ngoài:

import X.y   // `y' bound by explicit import 
    println("L16: "+y) // `y' refers to `Q.X.y' here 
    import P.X._ 
    println("OK: "+y) // `y' refers to `Q.X.y' here 

    locally { val x = "abc"  // `x' bound by local definition 
     import P.X._  // `x' and `y' bound by wildcard import 
//  println("L19: "+y) // reference to `y' is ambiguous here 
+0

Trước đây, https://issues.scala-lang.org/browse/SI-4270 –

+0

https://issues.scala-lang.org/browse/SI-9208 –

3

như đã giải thích trong

http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html

một nhập ký tự đại diện (như bạn đã viết) mang đến cho bất kỳ Swin g ngầm định nghĩa một ưu tiên khá cao và rõ ràng là ẩn của bạn.

Vì bạn đang biên soạn với SBT, nó sẽ không được dễ dàng hơn nhiều để vượt qua những điều sau thiết

scalacOptions ++= Seq(
    "-feature", 
    "-language:implicitConversions" 
) 

và ngừng lo lắng về đúng nơi để nhập scala.language.implicitConversions là gì?

+0

Bằng cách nào đó tôi tìm thấy nhập khẩu sạch hơn là một tùy chọn trình biên dịch. Có thể chỉ là tôi. – Suma

Các vấn đề liên quan