球拍对象的唯一标识符?

时间:2019-05-30 23:00:31

标签: racket

有没有办法在球拍中获取对象的唯一标识符?例如,当我们使用Racket的eq?运算符检查两个变量是否引用 same 对象时,它使用什么标识符来实现此比较?

我正在寻找类似python id function或Ruby object_id method之类的东西,换句话说,是某个函数id,使得(= (id obj) (id obj2))意味着(eq? obj obj2)是是的。

一些相关文档:

Object Identity and Comparisons

Variables and Locations

4 个答案:

答案 0 :(得分:4)

eq-hash-code是您想要的吗?

> (define l1 '(1))
> (define l2 '(1))
> (eq? l1 l2)
#f
> (eq-hash-code l1)
9408
> (eq-hash-code l2)
9412

答案 1 :(得分:2)

有一种方法可以通过ffi/unsafe获取对象的C指针,显然需要注意的是它是UNSAFE。

;; from https://rosettacode.org/wiki/Address_of_a_variable#Racket

(require ffi/unsafe)

(define (madness v) ; i'm so sorry
   (cast v _racket _gcpointer))

要使用它:

(define a (list 1 2))
(define b (list 1 2))

(printf "a and b have different address: ~a ~a\n"
        (equal? (madness a) (madness b))
        (eq? a b))

(printf "a and a have the same address: ~a ~a\n"
        (equal? (madness a) (madness a))
        (eq? a a))

(printf "1 and 1 have the same address: ~a ~a\n"
        (equal? (madness 1) (madness 1))
        (eq? 1 1))

尽管指针不是数字或标识符。这是一个不透明的对象...从某种意义上说,这是没有用的。您可以将真实对象与eq?一起使用。

我也不知道这种方法的任何保证。特别是,我不知道复制GC复制对象时指针是否会更新为最新值。

答案 2 :(得分:2)

这是使用弱哈希表的此类函数的实现。 使用弱哈希表可确保正确地垃圾回收对象 即使我们给了它一个ID。

&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&
127.0.0.1 - - [31/May/2019 11:21:53] "POST /book/ HTTP/1.1" 500 -
Traceback (most recent call last):
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 2328, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 2314, in wsgi_app
    response = self.handle_exception(e)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask_restplus\api.py", line 583, in error_router
    return original_handler(e)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1760, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\_compat.py", line 36, in reraise
    raise value
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 2311, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1834, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask_restplus\api.py", line 583, in error_router
    return original_handler(e)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1737, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\_compat.py", line 36, in reraise
    raise value
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1832, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1818, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask_restplus\api.py", line 325, in wrapper
    resp = resource(*args, **kwargs)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\views.py", line 88, in view
    return self.dispatch_request(*args, **kwargs)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask_restplus\resource.py", line 44, in dispatch_request
    resp = meth(*args, **kwargs)
  File "C:\Users\albert_lazaro\Documents\Projects\Generetis\generetis-backend-flask\app\main\controller\book_controller.py", line 33, in post
    return save_new_book(data=data)
  File "C:\Users\albert_lazaro\Documents\Projects\Generetis\generetis-backend-flask\app\main\service\book_service.py", line 28, in save_new_book
    viewable=0)
  File "<string>", line 4, in __init__

  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\orm\state.py", line 441, in _initialize_instance
    manager.dispatch.init_failure(self, args, kwargs)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\util\langhelpers.py", line 68, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\util\compat.py", line 129, in reraise
    raise value
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\orm\state.py", line 438, in _initialize_instance
    return manager.original_init(*mixed[1:], **kwargs)
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\ext\declarative\base.py", line 836, in _declarative_constructor
    setattr(self, k, kwargs[k])
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\orm\attributes.py", line 262, in __set__
    instance_state(instance), instance_dict(instance), value, None
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\orm\attributes.py", line 822, in set
    state, dict_, value, old, initiator
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\orm\attributes.py", line 830, in fire_replace_event
    state, value, previous, initiator or self._replace_token
  File "C:\Users\albert_lazaro\AppData\Local\Programs\Python\Python37-32\lib\site-packages\sqlalchemy\orm\util.py", line 168, in set_
    return validator(state.obj(), key, value)
  File "C:\Users\albert_lazaro\Documents\Projects\Generetis\generetis-backend-flask\app\main\model\book.py", line 52, in validates_isbn
    'isbn length must be minor or equal to 13 characters')
AssertionError: isbn length must be minor or equal to 13 characters

请注意,Sylwester的建议是正确的。标准是直接存储值。

答案 3 :(得分:1)

您很可能找不到身份,但是对象本身仅是eq?,没有别的。 eq?基本比较值的地址位置。因此,如果您想要一个ID,则可以将整个对象存储在该位置,并且它是唯一的。

位置是一个绑定。将其视为无法获得的地址,以及具有对象地址的地址。例如。绑定((lambda (a) a) 10)会将对象10的地址位置存储在第一个堆栈地址中,主体中的代码仅返回相同的地址。位置可以更改set!,但您永远不会得到它的内存位置。

对于Lisp系统来说,将值存储在指针中是很常见的。这意味着某些类型和值在地址处实际上没有对象,但是地址中包含系统知道的值和类型编码的对象。通常,即使小整数,字符,符号和布尔值在不同的时间构造,它们也可以等于指针。例如。 '(1 2 3)仅会使用3对,而不会为值1-3和()使用任何空格。