球拍什么时候会在函数中检查结构的类型?
When racket will check the struct's type in a function?
这个节目:
(struct pt (x y))
(define (distance p1 p2)
(sqrt (+ (sqr (- (pt-x p2) (pt-x p1)))
(sqr (- (pt-y p2) (pt-y p1))))))
(distance (pt 0 0) (pt 3.1415 2.7172))
工作正常。如果加一行:
(struct pt2 (x y))
然后
(distance (pt 0 0) (pt2 3.1415 2.7172))
遇到错误
pt-x: contract violation
expected: pt?
given: #<pt2>
我认为是因为函数 distance 使用“pt-x”和“pt-y”来检查结构的类型。在其他静态类型语言中,类型声明和类型检查会发生在函数的头部,像这样:
(define (distance p1:pt p2:pt)
所以作为球拍,如果在“(定义(距离p1 p2)”之后可能有100行代码,并且需要1分钟,然后行“(sqrt(+(sqr(-(pt -x p2) (pt-x p1)))", 发现类型错误,所以会浪费1分钟?
谢谢!
我不确定你所说的“浪费 1 分钟”是什么意思。
- 从某种意义上说,在调用
distance
之后,(pt-x p2)
可能需要1分钟才能执行?
- 或者从某种意义上说,整个程序可能需要 1 分钟才能执行
(pt-x p2)
?
如果你指的是第一个,你可以在distance
中添加一个合同。例如,
#lang racket
(struct pt (x y))
(define/contract (distance p1 p2) (-> pt? pt? number?)
(sqrt (+ (sqr (- (pt-x p2) (pt-x p1)))
(sqr (- (pt-y p2) (pt-y p1))))))
(distance (pt 0 0) (pt 3.1415 2.7172))
每次调用distance
时,都会检查p1
和p2
是否满足pt?
,如果检查失败,则立即报错。请注意,这发生在 运行 时间并且仅在调用 distance
时发生。程序可能运行长时间没有问题,然后执行(distance (pt2 0 0) (pt2 3.1415 2.7172))
,才会出现错误。
如果你指的是第二个,那么你根本不希望程序是 运行 以便发现错误。也就是说,您希望静态地发现错误。你需要使用 Typed Racket 或类似的东西。这类似于具有静态类型检查的语言。
#lang typed/racket
(struct pt ([x : Number] [y : Number]))
(: distance : pt pt -> Number)
(define (distance p1 p2)
(sqrt (+ (sqr (- (pt-x p2) (pt-x p1)))
(sqr (- (pt-y p2) (pt-y p1))))))
(distance (pt 0 0) (pt 3.1415 2.7172))
这个节目:
(struct pt (x y))
(define (distance p1 p2)
(sqrt (+ (sqr (- (pt-x p2) (pt-x p1)))
(sqr (- (pt-y p2) (pt-y p1))))))
(distance (pt 0 0) (pt 3.1415 2.7172))
工作正常。如果加一行:
(struct pt2 (x y))
然后
(distance (pt 0 0) (pt2 3.1415 2.7172))
遇到错误
pt-x: contract violation
expected: pt?
given: #<pt2>
我认为是因为函数 distance 使用“pt-x”和“pt-y”来检查结构的类型。在其他静态类型语言中,类型声明和类型检查会发生在函数的头部,像这样:
(define (distance p1:pt p2:pt)
所以作为球拍,如果在“(定义(距离p1 p2)”之后可能有100行代码,并且需要1分钟,然后行“(sqrt(+(sqr(-(pt -x p2) (pt-x p1)))", 发现类型错误,所以会浪费1分钟?
谢谢!
我不确定你所说的“浪费 1 分钟”是什么意思。
- 从某种意义上说,在调用
distance
之后,(pt-x p2)
可能需要1分钟才能执行? - 或者从某种意义上说,整个程序可能需要 1 分钟才能执行
(pt-x p2)
?
如果你指的是第一个,你可以在distance
中添加一个合同。例如,
#lang racket
(struct pt (x y))
(define/contract (distance p1 p2) (-> pt? pt? number?)
(sqrt (+ (sqr (- (pt-x p2) (pt-x p1)))
(sqr (- (pt-y p2) (pt-y p1))))))
(distance (pt 0 0) (pt 3.1415 2.7172))
每次调用distance
时,都会检查p1
和p2
是否满足pt?
,如果检查失败,则立即报错。请注意,这发生在 运行 时间并且仅在调用 distance
时发生。程序可能运行长时间没有问题,然后执行(distance (pt2 0 0) (pt2 3.1415 2.7172))
,才会出现错误。
如果你指的是第二个,那么你根本不希望程序是 运行 以便发现错误。也就是说,您希望静态地发现错误。你需要使用 Typed Racket 或类似的东西。这类似于具有静态类型检查的语言。
#lang typed/racket
(struct pt ([x : Number] [y : Number]))
(: distance : pt pt -> Number)
(define (distance p1 p2)
(sqrt (+ (sqr (- (pt-x p2) (pt-x p1)))
(sqr (- (pt-y p2) (pt-y p1))))))
(distance (pt 0 0) (pt 3.1415 2.7172))