Đây là một nỗ lực để đơn giản hóa một phần câu hỏi mà tôi đã yêu cầu here:Tôi làm cách nào để viết một Trait trong Julia với các kiểu mở?
Tôi muốn viết một số mã được đảm bảo hoạt động trên các loại đáp ứng các tiêu chí nhất định. Hãy nói rằng hôm nay tôi viết một số mã:
immutable Example
whatever::ASCIIString
end
function step_one(x::Example)
length(x.whatever)
end
function step_two(x::Int64)
(x * 2.5)::Float64
end
function combine_two_steps{X}(x::X)
middle = step_one(x)
result = step_two(middle)
result
end
x = Example("Hi!")
combine_two_steps(x)
Chạy công trình này:
julia> x = Example("Hi!")
Example("Hi!")
julia> combine_two_steps(x)
7.5
Sau đó một ngày khác tôi viết một số mã khác:
immutable TotallyDifferentExample
whatever::Bool
end
function step_one(x::TotallyDifferentExample)
if x.whatever
"Hurray"
else
"Boo"
end
end
function step_two(x::ASCIIString)
(Int64(Char(x[end])) * 1.5)::Float64
end
Và những gì bạn biết, chung tôi chức năng kết hợp vẫn hoạt động!
julia> y = TotallyDifferentExample(false)
TotallyDifferentExample(false)
julia> combine_two_steps(y)
166.5
Hoan hô! Nhưng, nói đó là một đêm khuya và tôi đang cố gắng thực hiện điều này trong ví dụ thứ ba. Tôi nhớ triển khai step_one
nhưng tôi quên triển khai step_two
!
immutable ForgetfulExample
whatever::Float64
end
function step_one(x::ForgetfulExample)
x.whatever+1.0
end
Bây giờ khi tôi chạy điều này, tôi sẽ gặp lỗi thời gian chạy!
julia> z = ForgetfulExample(1.0)
ForgetfulExample(1.0)
julia> combine_two_steps(z)
ERROR: MethodError: `step_two` has no method matching step_two(::Float64)
Bây giờ, tôi làm việc cho người quản lý sẽ KILL ME nếu tôi gặp lỗi thời gian chạy. Vì vậy, những gì tôi cần làm để cứu mạng sống của tôi là viết một Trait về cơ bản nói "nếu loại thực hiện đặc điểm này, thì an toàn để gọi combine_two_steps
."
Tôi muốn viết một cái gì đó giống như
using Traits
@traitdef ImplementsBothSteps{X} begin
step_one(X) -> Y
step_two(Y) -> Float64
end
function combine_two_steps{X;ImplementsBothSteps{X}}(x::X)
middle = step_one(x)
result = step_two(middle)
result
end
b/c sau đó tôi muốn biết rằng nếu combine_two_steps
là bao giờ cử, sau đó nó sẽ chạy mà không tăng một lỗi mà các phương pháp này don không tồn tại.
Tương đương, istrait(ImplementsBothSteps{X})
(là đúng) tương đương với combine_two_steps
sẽ chạy mà không có lỗi-từ-không tồn tại-of-yêu cầu-phương pháp.
Nhưng, như mọi người đều biết, tôi không thể sử dụng định nghĩa đặc điểm đó, bởi vì Y
không có ý nghĩa. (Trong thực tế, kỳ quặc đủ mã biên dịch mà không có lỗi,
julia> @traitdef ImplementsBothSteps{X} begin
step_one(X) -> Y
step_two(Y) -> Float64
end
julia> immutable Example
whatever::ASCIIString
end
julia> function step_one(x::Example)
length(x.whatever)::Int64
end
step_one (generic function with 1 method)
julia> function step_two(x::Int64)
(x * 2.5)::Float64
end
step_two (generic function with 1 method)
julia> istrait(ImplementsBothSteps{Example})
false
nhưng các loại không đáp ứng các đặc điểm mặc dù các phương pháp tồn tại cho một số Y
.) Suy nghĩ đầu tiên của tôi là tôi có thể thay đổi Y
một cái gì đó giống như Any
using Traits
@traitdef ImplementsBothSteps{X} begin
step_one(X) -> Any
step_two(Any) -> Float64
end
nhưng điều này không quá b/c các Any
thực sự được coi là một cái gì đó giống như Some
, không theo nghĩa đen những Any
loại (kể từ khi tôi không bao giờ thực hiện một phương pháp step_two
mà có thể mất bất kỳ loại như đầu vào), nhưng một số đặc biệt loại được chia sẻ trên cả hai dòng!
Vì vậy, câu hỏi đặt ra là: bạn sẽ làm gì trong tình huống này?Bạn muốn truyền xung quanh một "spec" (ở đây dưới dạng hợp đồng được thể hiện bởi Trait) sao cho bất kỳ lập trình viên nào đáp ứng được thông số được đảm bảo để có thể sử dụng hàm combine_two_steps
của bạn. trong định nghĩa của nó.
Có cách giải quyết khác không? Một cách tiếp cận tốt hơn để viết "spec" (ví dụ: "Không sử dụng Traits, sử dụng cái gì khác"?) Vv.
Nhân tiện, nó có vẻ gây tranh cãi, nhưng câu hỏi được liên kết ở trên và câu hỏi này đang đến lên thường xuyên trong một dự án tôi đang làm việc. Tôi về cơ bản bị mắc kẹt tại một rào cản gây ra bởi vấn đề này và có cách giải quyết xấu mà làm việc từng trường hợp, nhưng không có cách tiếp cận cho trường hợp chung.
Bạn có thể vui lòng đăng chi tiết không. –