Защо обектите не са разрешени като ключове в асоциативни масиви?

В PHP документацията се посочва:

Масивите и обектите не могат да се използват като ключове. Това ще доведе до предупреждение: Незаконен тип отместване.

AFAIK, PHP масивите са подредени хеш-карти. И така, защо само по себе си е забранено използването на обекти като ключове, има ли причина за това ограничение? Защо няма възможност да се имплементира хеш функция в клас, за да се използва като ключ?

Във връзка с това, има ли PHP реализация на хеш-карта, която решава този проблем?


person rob    schedule 10.12.2012    source източник
comment

Имам куп възли от всяка страна на централен възел. Опитвам се да намеря начин да позиционирам линиите на възлите така, че да отиват от дясната или лявата страна на възлите.

Така че за това: http://jsbin.com/ipuxub/4/edit?js,output

Искам линиите за възела Джери да отиват от дясната страна на Илейн, Джордж, Крамър и т.н.

Въпреки че не мисля, че това е възможно сега:

  1. Има ли начин да го принудите, да го подмамите или да го направите да изглежда по-добре?

  2. Ако променя кода на Cytoscape JS, някакви предложения откъде да започна или да разгледам или какво трябва да се промени?

  -  person Charles    schedule 10.12.2012
comment
@Charles работи като чар, благодаря!   -  person rob    schedule 10.12.2012


Отговори (2)


Ключовете трябва да са неизменни, за да работят. Ако вашите обекти са променливи, тогава те не могат да бъдат ключове. Това е вярно за всеки език, който ги прилага: Java, C# и т.н.

person duffymo    schedule 10.12.2012
comment
Въпрос (не съм експерт, просто съм любопитен): Ако обектите имат адрес на паметта (предполагам), този адрес на паметта не се променя (предполагам?) - ако такъв адрес на паметта не се променя, защо такъв адрес не се променя използван като ключ за това? - person Voldemort; 10.12.2012
comment
@Omega, интересно. Някои езици наистина могат да направят нещо подобно. Това обаче ще изисква междинно съпоставяне на транслацията между името на времето за изпълнение и адреса на паметта. Освен това, това би имало последици за езиците с вградено управление на паметта. - person Jason McCreary; 10.12.2012
comment
@duffymo Разбирам, че ключовете трябва да са неизменни, но не трябва ли да бъде отговорност на програмиста да използва само неизменни полета на клас за генериране на хеша? (както е например в Java) - person rob; 10.12.2012
comment
@JasonMcCreary удари гвоздея на главата в края. Ами ако вашият хеш е дефиниран в по-широк обхват от обект в него? Какво се случва, когато вашият обект излезе извън обхвата и бъде събран боклук? Вече нямате начин да стигнете до този ключ, освен ако случайно не сте съхранили предишния адрес на паметта. Но чакайте, какво ще стане, ако нов обект е записан на същия адрес в паметта? Ухо. - person Colin M; 10.12.2012
comment
@rob Всичко е променливо в PHP обект. Винаги. Дори частните/защитените свойства са променливи извън обхвата на обекта, използвайки отражение. Това би затруднило всякакъв вид почтеност. - person Colin M; 10.12.2012
comment
@duffymo Не съм сигурен, че съм съгласен с: Това е вярно във всеки език, който ги прилага. Разбира се, в Java и (iirc) ключовете за карта на python са променливи. - person Jim; 10.12.2012
comment
Не в Python. Можете да добавите променлив ключ към Map в Java, но бързо ще съжалявате. - person duffymo; 10.12.2012
comment
@duffymo Можете да се уверите, че хешът остава същият в Java, като използвате само неизменните полета на клас, за да го генерирате. Но признавам, че е опасно, ако не знаете какво правите... и затова може би е хубаво, че не е част от стандартната реализация на масива в PHP. - person rob; 11.12.2012

Вижте @duffymo за отговора.

Имайте предвид, че има нещо като "заобиколно решение", като използвате spl_object_hash като ваш ключ. Това връща низ, който е неизменен, който може да се използва като ключ и ще бъде същият за всеки обект, който заема този адрес в паметта. (Прочетете: spl_object_hash ще върне същата стойност за същия екземпляр, независимо къде е извикан или ако обектът е променен)

person Colin M    schedule 10.12.2012
comment
За съжаление spl_object_hash връща различна стойност при всяко извикване на скрипт, дори ако обектите са идентични. Това би го направило някак неудобно. - person Charles; 10.12.2012
comment
Е, по дефиниция те не са идентични. Те са различни обекти. Ще трябва да внедрите свой собствен equals метод или нещо подобно. По-добър въпрос: защо ви е необходимо сравнение на кръстосано извикване в хеш карта? Защо не намерите начин да създадете уникални идентификатори за тези обекти и да ги запазите в система, която е предназначена за това? - person Colin M; 10.12.2012