tôi có thể sử dụng gợi ý gỡ lỗi một tiềm ẩn:Scala: Cách nhập có thể ngăn chặn việc tìm kiếm giá trị tiềm ẩn?
Tôi muốn sử dụng ngầm, x
:
type T
trait HasT {
implicit def x: T = ...
}
Nhưng tôi cũng cần một nhập ký tự đại diện từ một số gói foo
. Tôi đã thử hai cách khác nhau để giới thiệu cả hai:
class UseT extends HasT {
import foo._
implicitly[T] // fails! "could not find implicit value"
// use foo stuff
}
class Use T {
object hasT extends HasT
import hasT.x
import foo._
implicitly[T] // fails! "could not find implicit value"
}
Cả hai thất bại với "không thể tìm thấy" (không phải "giá trị impligits implicits").
Điều này xảy ra trong khi số nhận dạng ngầm x: T
có thể truy cập tại điểm gọi phương thức thông qua kế thừa hoặc nhập.
Giải pháp thay thế của tôi là rebind x thành giá trị ngầm định trước khi nhập. Cả hai công việc sau đây:
implicit val x2: T = implicitly[T]
import foo._
implicitly[T] // works!
và
implicit val x2: T = x
import foo._
implicitly[T] // works!
giá trị gì có thể trong foo gây ra hành vi này? Lần đầu tiên tôi đoán là có một số ẩn ý cạnh tranh trong foo
, nhưng nếu nó là ưu tiên cao hơn, implicitly
sau đây sẽ vẫn hoạt động, và nếu nó là một ẩn ý mơ hồ, tôi sẽ nhận được một lỗi khác nhau khác nhau.
Một đoán thứ hai, được cung cấp bởi dặm Sabin, là implicit shadowing. Tôi đã làm rõ bài viết của mình để loại trừ khả năng đó. Trường hợp đó sẽ phù hợp với lỗi của tôi nếu tôi đã thử package hasT extends HasT; import hasT._
, nhưng Như som-snytt chỉ ra, hai trường hợp đó sẽ không dẫn đến bóng tối.
Trong trường hợp cụ thể của tôi, điều này có thể được xác nhận bằng cách thay đổi tên của ngầm tôi đang cố gắng sử dụng.
(Tôi phải bỏ lỡ một số publishLocal
hoặc reload
)
Bây giờ tôi thực sự đang cố gắng sử dụng trơn. Các ngầm T
trên thực sự là một ánh xạ loại cột:
import slick.driver.JdbcProfile
class Custom { ... } // stored as `Long` in postgres
trait ColumnTypes {
val profile: JdbcProfile
import profile.api._ // this is `foo` above
type T = profile.BaseColumnType[Custom]
implicit def customColumnType: T =
MappedColumnType.base[Custom, Long](_.toLong, Custom.fromLong)
}
class DatabaseSchema(val profile: JdbcProfile) extends ColumnTypes {
// `implicitly[T]` does not fail here.
import profile.api._ // this is also `foo` above
// `implicitly[T]` fails here, but it's needed for the following:
class CustomTable(tag: Tag) extends Table[Custom](tag, "CUSTOMS") {
// following fails unless I rebind customColumnType to a local implicit
def custom = column[Custom]("CUSTOM")
def * = custom
}
}
Loại api
/foo
là JdbcProfile.API
. Vi phạm tiềm ẩn có thể là here, nhưng tôi không thể biết tại sao. Tôi sẽ cố gắng ngăn chặn một số người trong số những người được nhập khẩu và xem nếu tôi có thể thu hẹp nó xuống.
dụ giảm của bạn biên dịch. Nó được cho là? Tôi nhận thấy bạn đã không bí danh 'T' thành' profile.api.BaseColu ... '. Có lẽ điều đó cũng không quan trọng. –
@ som-snytt Phải! Nó sẽ không biên dịch nếu ngầm định được đặt tên là 'timeColumnType'. Miles đã đúng để nghi ngờ ẩn bóng. – stewSquared
Tôi đã bắt đầu đặt tên cho implicits của mình bằng đường dẫn gói đầy đủ để tránh điều này trong tương lai. – stewSquared