Около года назад был PR, добавляющий аннотации для GDScript (# 9469). Он был отклонен главным образом потому, что для него не было прямого использования (нет данных в дереве синтаксического анализа, его могли использовать только сторонние инструменты).
Это предложение состоит в том, чтобы добавить некоторое использование аннотаций таким образом, чтобы сделать GDScript более расширяемым без добавления в него дополнительных ключевых слов.
Для чего можно использовать аннотации?
export
подсказки. Сейчас он использует собственный синтаксис для каждого типа. С помощью аннотаций он мог напрямую устанавливать использование и подсказку для PropertyInfo, улучшая использование новых дополнений к Inspector без необходимости взламывать новый синтаксис в парсере GDScript.export
, просто подсказки переместились бы в аннотации. Тип можно определить с помощью подсказок типа.export
(# 4378, # 10303).onready
аннотацией.setget
(это странный синтаксис, когда вам нужен только геттер).master
, slave
, sync
, remote
).tool
) или только в режиме отладки (связано с # 12837).Преимущества
Каждый раз, когда добавляется новое ключевое слово, для его обработки требуются изменения в токенизаторе и анализаторе GDScript. В частности, синтаксический анализ export
довольно запутан и смешан с другим синтаксическим анализом, связанным с классами.
С аннотациями будет меньше работы по добавлению определенного атрибута (например, export, setget, onready), вместо этого нужно будет только проверить, какие аннотации присутствуют.
Недостатки
Добавление поддержки аннотаций потребует больше изменений в синтаксический анализатор, чем одно ключевое слово. Это также может побудить людей предлагать новые функции как «просто аннотацию».
Синтаксис
У меня нет особых предпочтений к синтаксису, но я представляю себе что-то вроде декораторов Python. Однако это может сбивать с толку пользователей Python, поскольку аннотации - это не то же самое, что декораторы.
<strong i="41">@onready</strong>
var my_sprite = $Sprite
Для передачи аргументов он может работать как функции:
@export_hint(ENUM)
@export_hint_string("Attack,Defense")
export var my_enum : int = 0
Возможно без скобок:
<strong i="48">@export_hint</strong> ENUM
<strong i="49">@export_hint_string</strong> "Attack,Defense"
export var my_enum : int = 0
Или, возможно, используйте именованные параметры (и избегайте ключевого слова):
<strong i="53">@export</strong> type=String hint=MULTILINE
var my_text = ""
Или что-то другое.
Пользовательские аннотации
Неизвестные аннотации будут просто проигнорированы (возможно, с предупреждением). Таким образом, сторонние инструменты могут анализировать аннотации и предлагать другие возможности, например создание документации.
Также можно добавить API самоанализа: get_method_annotations()
, get_property_annotations()
или что-то в этом роде. Таким образом, плагины, которые, скажем, ожидают скриптов, могут использовать аннотации, чтобы решить, какой метод вызвать, вместо использования жестко заданного имени.
Просто чтобы я правильно понимаю пользовательские аннотации, у меня могло бы быть что-то вроде этого:
<strong i="6">@description</strong> "Adds two numbers and returns the result."
<strong i="7">@parameter</strong> name=num1 type=float description="The first number"
<strong i="8">@parameter</strong> name=num2 type=float description="The second number"
<strong i="9">@returns</strong> type=float description="num1 and num2 added together"
func add(num1, num2):
return num1 + num2
И я мог бы вызвать функцию, скажем get_annotations("add")
, которая вернет эти аннотации? Даже если эти аннотации не распознаются Годо как какое-то встроенное ключевое слово / аннотация?
@ LikeLakers2 да, в этом суть.
Мне это нравится, я не знаю, какова реализация, но в коде GDscript это выглядело бы намного чище, чем то, как оно выглядит сейчас. Специально для примера setget.
Это очень полезно, но для удобства чтения должно допускать использование однострочных операторов. Например,
<strong i="6">@onready</strong> var a = $A
должно быть разрешено. В противном случае это добавит тонну новых строк и в этом случае приведет к потере полезного из уже готового.
Что-то вроде
<strong i="10">@onready</strong>
var a = $A
var b = $B
var c = $C
Было бы полезно применить одну и ту же аннотацию к нескольким операторам.
Кроме того, двоеточие можно использовать, чтобы указать, где заканчивается аннотация и где начинаются затронутые операторы, чтобы они соответствовали остальной части GDScript.
Если аннотации можно анализировать с четким началом и концом, тогда нет необходимости в точках с запятой и при необходимости их можно поместить в ту же строку (если они используют '()', например, или не имеют аргументов)
Я не думаю, что vnen намеревался удалить старые короткие ключевые слова?
Также может помочь ручка с маркером.
Поздно к вечеринке, но вас очень интересует, как это может предоставить категории для переменных экспорта и создать разделы инструментов / сценариев отладки?
Ориентировочно добавляя дорожную карту 3.2, я действительно хотел бы, чтобы это было реализовано раньше, чем позже, чтобы улучшить удобство использования редактора.
#### поступает непопулярное мнение:
почему синтаксис gdscript так сильно модифицируется? Изначально он был разработан, чтобы быть простым, легким в освоении и интуитивно понятным. Я боюсь, что со всеми этими новыми дополнениями (типизированные gds, аннотации) это запутает новых разработчиков. например, если бы новый человек в godot посмотрел учебник и увидел код из сообщения LikeLakers2, я бы предположил, что у него взорвется голова. во всяком случае, им придется задать кучу вопросов об этом / как это работает и т. д.
Я полностью понимаю любовь всех к GDS и то, как участники хотят сделать их лучше и т. д. Я просто чувствую, что может быть возможный разрыв между настоящими разработчиками игр и участниками (не говоря, что участники не являются разработчиками игр, просто говоря, как некоторые функции на самом деле не нужны). не всем нужно использовать эти функции. Я просто боюсь, что GDS может все больше и больше отклоняться от своей простоты, вот и все. этого уже более чем достаточно ...
Кроме того, наличие трех строк для ключевого слова экспорта очень громоздко по сравнению с простым указанием всего в одной строке. например: onready var my_sprite = $Sprite
намного чище (по крайней мере, для меня)
а что касается пункта №4, это можно сделать в редакторе AFAIK. Кроме того, imo, наличие аннотаций повсюду в коде для «отключения определенных предупреждений» может привести к очень грязному коду.
почему синтаксис gdscript так сильно модифицируется? Изначально он был разработан, чтобы быть простым, легким в освоении и интуитивно понятным. Я боюсь, что со всеми этими новыми дополнениями (типизированные gds, аннотации) это запутает новых разработчиков.
Большинство (если не все) изменений синтаксиса GDScript совместимы со старым кодом. Основная цель - повысить продуктивность разработчиков с помощью GDScript, например:
match
позволяют использовать операторы switch-case (которые были весьма востребованы) и даже улучшают это, позволяя людям легко сопоставлять массивы и словари.onready
переменные (которые были нововведением в 2.x) конкретизируют шаблон, который часто использовался, а именно инициализацию переменных в _ready
.Я просто чувствую, что может быть возможный разрыв между настоящими разработчиками игр и участниками.
Это открытое сообщество. Разработчики игр могут прийти и высказать свое мнение, как и вы. В любом случае пройдет немало времени, прежде чем аннотации станут реальностью.
[...] я просто боюсь, что GDS может все больше и больше отклоняться от своей простоты, вот и все. этого уже более чем достаточно ...
Если бы он уже был достаточно хорош, мы бы не получили для него запросы на добавление новых функций.
Кроме того, наличие трех строк для ключевого слова экспорта очень громоздко по сравнению с простым указанием всего в одной строке. например: onready var my_sprite = $ Sprite намного чище
Синтаксис еще не доработан. Вполне вероятно, что он не заменит сразу ключевые слова onready
и export
.
Идея мне очень нравится, очень нравятся атрибуты в C #.
Также могут быть интересны аннотации классов и сигналов.
Плагины Inspector, которые автоматически вступают в действие, независимо от того, имеют ли свойство, метод или класс конкретную настраиваемую аннотацию, были бы пустяком.
Что касается синтаксиса, я бы предпочел что-то, что можно было бы также написать в одной строке, но это не так важно.
Каким может быть процесс определения пользовательских аннотаций? Я бы предпочел, чтобы они не определялись каждый раз в коде свободно, а создавались пользователем с однозначным определением, как классы.
Я думаю, что это требует большего внимания, я думаю, было бы здорово добавить к языку (в качестве необязательного синтаксиса и т. Д.), Чтобы не сбивать с толку новичков, пытающихся вмешаться.
Я думаю, что можно посмотреть на следующий синтаксис:
<strong i="7">@export</strong> type=String, hint=MULTILINE
добавление запятой между «параметрами», я думаю, сделало бы его немного более согласованным с текущим синтаксисом, например:
export (String, MULTILINE) var my_var
первая версия немного более подробна, но я думаю, что она также делает ее более явной, и с автозаполнением это не должно сильно повредить :)
В будущем следует продолжить обсуждение синтаксиса. В целом идея мне нравится.
Аннотации - хороший способ внедрения конфигурации. Но разделение конфигурации и кода может быть более чистым подходом, ИМО. Может быть, добавление их в виде файлов заголовков будет более полезным.
Из комментария @ bojidar-bg ...
В любом случае пройдет немало времени, прежде чем аннотации станут реальностью.
Может кто-нибудь объяснить, в чем заключается проблема «блокировки», которая задерживает эту реализацию? Это просто знакомство с GDScript / персоналом, или есть определенные функции, которые необходимо реализовать заранее для поддержки аннотаций?
Что ж, с момента моего комментария прошло довольно много времени, так что я думаю, что это уже доказывает?
Основным препятствием для поддержки аннотаций будет согласие разработчиков ядра по синтаксису и семантике. После этого реализация должна быть относительно простой.
Нам нужно обсудить это с @reduz, поскольку он предпочитает, чтобы аннотации предназначались только для метаданных, они не должны влиять на поведение скрипта или редактора. Это сделало бы мое первоначальное предложение совершенно бессмысленным.
Я по-прежнему считаю, что аннотации достаточно ясны, особенно при замене отдельных ключевых слов ( onready
, master
, puppet
и т. Д.). Но нам еще нужно прийти к консенсусу.
Я думаю, что это было бы фантастическим дополнением к GDScript, как описано. Я не думаю, что его следует ограничивать метаданными, он определенно должен перекрыть многие ключевые слова, которые используются для переменных, особенно export
которые в некоторых случаях может быть трудно читать; Я чувствую, что разбиение его на несколько утверждений помогает понять.
Его также можно использовать для элегантного решения этой проблемы 3-летней давности # 6204:
<strong i="8">@export</strong>
<strong i="9">@export_tooltip</strong> "The name used when displaying this item in the inventory and in shops."
var display_name := ""
Я также согласен с тем, что они должны поддерживать не только метаданные. Это упростило бы большую часть логики и улучшило бы читабельность imo.
Я согласен с @willnationsdev и хотел бы соединять сигналы по коду с использованием аннотаций, что-то вроде этого может действительно улучшить читаемость кода:
@connect("timeout")
func _on_Timer_timeout():
...
@rluders, возможно, при условии, что сценарий находится на узле Timer
.
@Zylann, конечно. Простой пример. Он может поддерживать "целевые" параметры и опускать их для самостоятельного подключения. Например, если сценарий выполняется за пределами Timer
:
@connect("timeout", $Timer)
func _on_Timer_timeout():
...
Я понятия не имею, как это можно реализовать, но мне бы очень хотелось увидеть аннотации в gds, особенно для ключевых слов. И для записи, я бы предпочел, чтобы вместо точки с запятой или новой строки для разделения аннотаций использовался '()'.
Было бы даже лучше, если бы мы могли создавать собственные аннотации + полноценные процессоры аннотаций.
@Zylann, конечно. Простой пример. Он может поддерживать "целевые" параметры и опускать их для самостоятельного подключения. Например, если сценарий выполняется за пределами
Timer
:@connect("timeout", $Timer) func _on_Timer_timeout(): ...
Это может поддерживаться плагином каким-то образом, я бы не стал делать это основной функцией.
Плагины могут стать еще более мощными.
все, что я могу сказать, это то, что я рад, что изучил gdscript до того, как эти вещи были реализованы, потому что
@export_hint(ENUM)
@export_hint_string("Attack,Defense")
export var my_enum : int = 0
было бы очень сложно разобрать для меня, как новичка
@sleepcircle Мы постараемся сделать GDScript простым во всех случаях. Так что здесь не нужно быть саркастичным: код, который вы процитировали, был всего лишь предложением, а не синтаксисом будущего.
Простите, я не пытался быть саркастичным. Я просто предполагал, поскольку большинство, казалось, одобряло эти дополнения, что они были неизбежны.
Просто хотел выложить свои 0,02 доллара в качестве инструктора по разработке игр. Предупреждение: излишне длинный комментарий, который мало что дает, просто мой 5-летний опыт преподавания программирования о том, как новые разработчики это воспримут.
Я думаю, что при разработке новых языковых идиом, таких как аннотации, важно использовать все возможные возможности. Например, с connect
, теперь он отлично работает, поскольку для нового разработчика имеет смысл вызвать функцию, которая принимает параметры и имеет некоторые побочные эффекты.
Если @
использовалось исключительно для метаданных, то каждый раз, когда новый разработчик видит @
он распознает его как метаданные, не влияющие на логику их кода. Если это повлияет на логику, важно, чтобы мы не добавляли новые идиомы, которые иногда используются как x, а иногда как y .
Прямо сейчас для изменения переменной есть префиксы, суффиксы и альтернативы var. Я перечислю некоторые вещи, которые не обязательно являются «модификаторами переменных», но новые разработчики могут видеть их такими.
onready
, export(...)
onready
влияет на загрузку переменных времени выполнения, export
- это своего рода подсказка / метаданные редактора. Когда их используют в одном месте, кажется, что их поведение должно быть каким-то образом связано, хотя на самом деле это не так.class_name
, extends
, signal
, enum
, const
, func
setget
export
в том смысле, что это скорее простое ключевое слово для разработчиков, а не логический сдвиг. Я вижу здесь людей, придерживающихся разных мнений, хотяvar x : int = 5
const
похож на setget в том, что он изменяет опыт разработчика больше, чем инструмент для самой игровой логики.Итак, теперь давайте посмотрим на добавление аннотаций.
Аннотации были бы совершенно новой концепцией / идиомой, которую нужно было бы преподавать новым разработчикам. В идеале новые разработчики должны уметь быстро освоиться и делать вещи, зная как можно меньше идиом, чтобы они могли органично подбирать новые идиомы по мере того, как они становятся для них полезными. Думайте об этом как о дереве технологий.
Мне кажется, что уровень 3-4 - это основная цель для аннотаций. Я бы дал своим ученикам две высоты в лифте для двух разных реализаций:
Я обучал несколько разработчиков Годо, и я думаю, что делать аннотации по крайней мере вариант уровня 3 и максимум уровня 4. Я бы предпочел не показывать им символ @
пока они уже не будут создают целостные, достаточно сложные игры и стремятся улучшить их процесс .
Это означает, что я придерживаюсь мнения, что мы используем аннотации исключительно для сокращений разработчиков, которые не важны для функциональности игры / имеют альтернативные реализации или просто для документации, поскольку легко сказать людям «изучайте аннотации, когда вы создаете более крупные проекты, для которых нужна документация».
Конкретные моменты из ветки:
_ready
а перспектива вложенных аннотаций означает, что onready
писать гораздо реже.@type(const int)
@type(enum)
, что объединит их всех как сахар, ориентированный на разработчиков.Опять же, не большой вклад, но пища для размышлений, когда вы думаете о том, какие функции следует скрывать под аннотациями. Я думаю, что это отличная идея, но неясно, где именно они подходят. Извините за длину, я всегда слишком многословен.
Мне это не нравится.
Я не хочу иметь кучу аннотаций для каждого поля, свойства и метода
Я бы предпочел иметь больше ключевых слов
если людям не нравится множество ключевых слов, мы можем удалить некоторые из них
export MyClass : Node2D # export replaces class_name, : replaces extends
signal mySignal #signal is kept
group(MyHeader, "res://icon.png" )
export var my_property : Array(int) setget _set_my_property, _get_my_property # : replaces export type
var test = 0 # no need for onready. variables declared outside of _ready automatically try to be onready vars
#others are kept
Я полностью согласен с первоначальным предложением.
Я не не согласен с приведенными выше комментариями, но плюсы значительно перевешивают минусы.
@ Shadowblitz16 Многие из этих предложений сбивают людей с толку по следующим причинам ...
export MyClass : Node2D # export replaces class_name, : replaces extends
export
, class_name
, :
и extends
каждый настраивает 4 полностью отдельных точки данных и системы. Вы не можете просто переключить их, не повлияв на другие вещи безвозвратно.
export
настраивает сгенерированный объект PropertyInfo, который отправляется инспектору для создания графического интерфейса редактора.class_name
регистрирует сценарий как глобальный класс в ScriptServer. Технически это не имеет ничего общего с системой типов. Это часть «статической типизации» GDScript только постольку, поскольку она просто создает глобальный экземпляр скрипта во время синтаксического анализа, а не во время выполнения.:
используется для дополнительных подсказок типа. Если вы не убедите людей постоянно делать GDScript статически типизированным и / или не предложите альтернативный синтаксис подсказки типа, нет никакого способа перепрофилировать токен двоеточия.extends
используется для унаследованного класса (как вы знаете). Это довольно распространенный синтаксис на других языках, и вся документация и руководства уже используют этот метод. Не будет сильного стимула отказаться от этого и создать больше работы по чисто косметическим причинам.group(MyHeader, "res://icon.png")
Мне непонятно, что это вообще может сделать. Я имею в виду, похоже, что узел будет добавлен в группу «MyHeader» (что может иметь смысл), но для чего нужен значок? Группы не имеют связанных с ними значков.
export var my_property : Array(int) setget _set_my_property, _get_my_property # : replaces export type
Как было сказано ранее, все это влияет на разные системы, а не на одну и ту же систему. Кроме того, могут быть случаи, когда вы хотите, чтобы тип значения или его инициализация были гибкими. Например, в динамическом GDScript вы можете сделать что-то вроде этого:
onready export(NodePath) var the_node = get_node(the_node)
var test = 0 # no need for onready. variables declared outside of _ready automatically try to be onready vars
Инициализировать данные до уведомления о готовности не имеет смысла. Сценарии связаны с классом Object, а не с классом Node. Свойства скрипта инициализируются во время построения. Это не изменится, даже когда вы перейдете к конструктору класса Node. Уведомление _ready()
происходит намного позже после создания экземпляра. Различие по умолчанию для инициализации переменных между объектами и узлами было бы чрезвычайно запутанным и привело бы к большому непредсказуемому поведению для тех, кто изучает и использует Godot.
Я не хочу отвергать ваши предложения, а просто объясняю, почему люди не видят оправдания этих предлагаемых изменений.
@willnationsdev все в порядке, я понимаю
как насчет аннотаций и дополнительных ключевых слов
таким образом пользователи могут использовать аннотации, если они хотят, и ключевые слова, если они не хотят иметь десятки аннотаций для каждого поля.
Изменить: обратите внимание на C # как атрибуты, которые позволяют вам комбинировать их так ..
[Attribute1(), Attribute2()]
однако, хотя это может помочь уменьшить количество строк, это все еще немного уродливо
@ Shadowblitz16 Мы бы предпочли иметь только один очевидный способ делать что-то, когда это возможно. Наличие двух разных синтаксисов противоречило бы этой цели.
@Calinou Я думаю, что gdscript следует оставить как есть, если люди не могут пойти на компромисс.
1 - это без надобности нарушает обратную совместимость
2 - он создает файлы большего размера и менее читаемый код
3 - это заставляет людей переходить на новую систему, к которой они не привыкли.
4 - это заставляет людей использовать систему, которую они могут не захотеть
1 - это без надобности нарушает обратную совместимость
2 - он создает файлы большего размера и менее читаемый код
3 - это заставляет людей переходить на новую систему, к которой они не привыкли.
4 - это заставляет людей использовать систему, которую они могут не захотеть
Честно говоря, это довольно плохие аргументы. 3 из этих 4 пунктов присущи любым большим изменениям в API, и первое из них можно обойти, сохранив некоторое время совместимость со старой системой на основе ключевых слов (вероятно, с предупреждением об устаревании).
_Редактировать: мы могли бы также предоставить инструмент автоматического преобразования. _
Что касается пункта 2, хотя я думаю, что все согласятся с тем, что аннотации могут привести к файлам с большим количеством строк, большинство людей здесь не согласны с тем фактом, что это создает менее читаемый код.
@groud это использует аннотации для ненужных вещей
1 - почему нам нужно отказаться от того, что работает?
2 - его менее читабельно, если вам нужно прокрутить вниз на 5 строк, чтобы увидеть поле
оба не подходят для аннотаций
Определения членов - единственное, для чего я действительно вижу, что это хорошо, и они должны быть сворачиваемыми, в этом случае это не так.
@groud это использует аннотации для ненужных вещей
В этой теме было представлено множество вариантов использования. Будь то документация, самоанализ, более сложные плагины ... существует масса вариантов использования аннотаций, которые нельзя охватить ключевыми словами.
1 - почему нам нужно отказаться от того, что работает?
Для этого есть масса причин. Любая функция может нуждаться в развитии, чтобы обеспечить более чистый API, большую гибкость и т. Д. И как только новая версия будет широко использоваться, по возможности лучше удалить совместимость с предыдущей версией, так как это определенно требует затрат на обслуживание.
2 - его менее читабельно, если вам нужно прокрутить вниз на 5 строк, чтобы увидеть поле
Не нужно преувеличивать. Цель обсуждения такого предложения - позволить синтаксису, достаточно интеллектуальному, чтобы избежать таких проблем. IMHO, подсказки экспорта могут быть интегрированы в качестве аргументов в аннотации экспорта (при условии, что у нас может быть именованная система аргументов, я думаю). В таких ситуациях система могла занимать еще меньше места, чем раньше.
Кроме того, мы могли бы также представить, что аннотации располагаются в тех же строках, что и поле. Не думаю, что это может вызвать проблемы.
экспорт - это в основном общедоступное ключевое слово для редактора
onready - это в основном объявление var перед запуском скрипта
оба не подходят для аннотаций
Что ж, у вас, вероятно, есть предвзятые представления о том, для чего нужны аннотации. Я действительно думаю, что этот вариант использования идеально подходит для системы аннотаций (и похоже, что многие люди). Но на самом деле, я думаю, каждую ситуацию нужно обсуждать индивидуально.
Я не считаю аргумент «линии» особенно хорошим. Даже если аннотации не позволяют напрямую использовать несколько операторов в строке (или «префиксную» форму), вы все равно можете использовать ;
в качестве разделителя.
<strong i="7">@onready</strong> var my_sprite = $Sprite
@onready; var my_sprite = $Sprite
@export_hint_string("Attack,Defense")
@export_hint(ENUM) export var my_enum : int = 0
@export_hint_string("Attack,Defense")
@export_hint(ENUM); export var my_enum : int = 0
<strong i="8">@export_hint_string</strong> "Attack,Defense";
<strong i="9">@export_hint</strong> ENUM export var my_enum : int = 0
<strong i="10">@export_hint_string</strong> "Attack,Defense"
<strong i="11">@export_hint</strong> ENUM; export var my_enum : int = 0
<strong i="12">@export</strong> type=String hint=MULTILINE; var my_text = ""
# more options
@export(type = String, hint = MULTILINE) var my_text = ""
@export(type = String, hint = MULTILINE); var my_text = ""
@export(String, hint = MULTILINE) var my_text = ""
# I personally prefer this one (positional and named args supported, default/optional args too)
@export(String, MULTILINE) var my_text = ""
@export(String, hint = MULTILINE) var my_text = ""
@export(type = String, hint = MULTILINE) var my_text = ""
@export(int, ENUM, "Attack,Defense") var my_enum:= 0
Изменить: О, я был слишком медленным, @groud уже обратился к аргументу строк. Ну, по крайней мере, эти несколько примеров кода добавили что-то в эту ветку.
это ваше мнение, ребята.
Я лично считаю @ некрасивым
РЕДАКТИРОВАТЬ:
так как же будет работать объявление члена?
это было бы ужасно
<strong i="10">@description</strong> "Adds two numbers and returns the result."
<strong i="11">@parameter</strong> name=num1 type=float description="The first number"
<strong i="12">@parameter</strong> name=num2 type=float description="The second number"
<strong i="13">@returns</strong> type=float description="num1 and num2 added together"
func add(num1, num2):
return num1 + num2
если его не удалось свернуть с начала @description
до начала func
Я считаю, что аннотации не предназначены для замены типов (как, похоже, ваш пример). Если вам не нужны аннотации документации, вам не придется их использовать:
func add(num1: float, num2: float) -> float: return num1 + num2
Эта путаница, вероятно, проистекает из неидеальной ситуации с подсказками экспорта, когда, насколько мне известно, вы не можете использовать реальные типы (и проблема отсутствия общих типов, которые неожиданно поддерживают экспорт подсказок для некоторых типов, таких как массив).
Я лично считаю @ некрасивым
так как же будет работать объявление члена?
это было бы ужасно
На других языках для этой цели обычно служат комментарии, а не аннотации, и они обычно являются такими же или более подробными, чем было предложено. В семействе языков C (наиболее популярных языках) @
довольно часто используется для аннотаций (например, Java, JavaScript, TypeScript, Scala, а также из того, что я читал на Python).
TypeScript (я считаю, что типы в документах не требуются, и инструменты могут использовать фактические типы):
/** Adds two numbers and returns the result.
* <strong i="16">@param</strong> num1 {float} The first number
* <strong i="17">@param</strong> num2 {float} The second number
* <strong i="18">@return</strong> {float} num1 and num2 added together
**/
const add = (num1: number, num2: number): number => num1 + num2;
Функциональный вкус:
@description("Adds two numbers and returns the result.")
@parameter(num1, "The first number", type=float)
@parameter(num2, "The second number", type=float)
@returns("num1 and num2 added together", type=float)
func add(num1: float, num2: float) -> float:
return num1 + num2
без повторяющихся типов:
@description("Adds two numbers and returns the result.")
@parameter(num1, "The first number")
@parameter(num2, "The second number")
@returns("num1 and num2 added together")
func add(num1: float, num2: float) -> float:
return num1 + num2
беспареновый аромат:
<strong i="28">@description</strong> "Adds two numbers and returns the result."
<strong i="29">@parameter</strong> num1 "The first number"
<strong i="30">@parameter</strong> num2 "The second number"
<strong i="31">@returns</strong> "num1 and num2 added together"
func add(num1: float, num2: float) -> float:
return num1 + num2
Мне больше всего нравится этот синтаксис для комментариев к документам. Я все еще не уверен в использовании аннотаций для целей документации, поскольку для аннотаций, не относящихся к документации, я бы предпочел синтаксис, подобный func.
Я использовал имена аннотаций из предыдущего примера, @parameter
может быть просто @param
как и в других языках, @description
может быть @desc
, @descr
или @func
.
В GodoDoc я использую синтаксис, основанный на TypeScript (TypeDoc, который сам основан на JSDoc и Javadoc), и, на мой взгляд, он работает достаточно хорошо:
## Same as [[bool_]], but `on_false`/`on_true` are functions.
## Only selected function will be called and its return value will be returned from `bool_lazy`.
## <strong i="44">@typeparam</strong> T {any} Return type
## <strong i="45">@param</strong> cond {bool} Condition
## <strong i="46">@param</strong> on_false {FuncLike<T>} Function to call and return its result when `cond` is `false`
## <strong i="47">@param</strong> on_true {FuncLike<T>} Function to call and return its result when `cond` is `true`
## <strong i="48">@return</strong> {T}
func bool_lazy_(cond: bool, on_false, on_true): return GGI.bool_lazy_(cond, on_false, on_true)
var bool_lazy = funcref(self, "bool_lazy_")
если его не удалось свернуть с начала @description до начала func
Да, как правило, сворачивание и параметры сворачивания по умолчанию были бы хорошим дополнением к редактору (сворачивание на основе типа блока, например, вы можете включить в настройках, что внутренние классы будут сворачиваться по умолчанию).
Мне нравится возможность помещать аннотацию впереди или выше, для этого неплохо использовать @annotation(a, b)
, с необязательными скобками, если не указаны параметры. Возможность вставки вперед обеспечивает ту же скорость записи, что и сегодняшнее ключевое слово, учитывая, что export
и onready
очень распространены для свойств.
Однако с точки зрения использования мне тоже не нравится документация. Я привык к аннотациям, влияющим на программу (даже если косвенно), в то время как документация часто утроила их количество для использования в виде комментариев, затем появлялась повсюду и выделялась так же, как функциональные аннотации ... она не подходит для чего-то что повсеместно. В принципе, мне нравится то же использование аннотаций, которое можно найти в C #, что приводит к тому, что гораздо меньше аннотаций нужно писать поверх членов (обычно они довольно редки, не каждый должен писать 5 строк, как показали некоторые примеры) . Если аргумент заключается в том, что у Годо нет API для указания документов сценария, то проблема в том, что ее нельзя решить исключительно с помощью аннотаций IMO. По крайней мере, я предполагаю, что это можно было бы использовать по желанию, но я бы не хотел, чтобы меня заставляли делать это таким образом, что я считаю неудобным для полномасштабной документации. (к тому же скрипты - это не только GDScript, и крайний случай использования _get_property_list
делает это еще более неудобным)
Думаю, я полностью согласен с тобой, Зиланн. Я бы лично разрешил такой синтаксис для экспорта (или уже готов), например, ключевых слов:
# No parenthesis when there are no parameters
<strong i="6">@export</strong> var myvar
# With parenthesis for parameters
@export(ENUM, "Up,Down,Left,Right") var myvar2
# Being able to write the annoation on the line before
@export(ENUM, "Up,Down,Left,Right")
var myvar2
Что касается части документации, я бы еще больше упростил синтаксис (на примере @mnn ):
<strong i="11">@description</strong> "Adds two numbers and returns the result."
<strong i="12">@parameter</strong> "The first number" # No need to name the args if they are ordered
<strong i="13">@parameter</strong> "The second number"
<strong i="14">@returns</strong> "num1 and num2 added together"
func add(num1: float, num2: float) -> float:
return num1 + num2
Однако я согласен, что разработка другой системы является обязательной, чтобы документация могла быть написана в другом месте. Я бы сказал, что в json, XML или первом файле. Документация в коде подходит не для каждого проекта, и я согласен, что добавление большого количества аннотаций только для документации может раздражать и в некоторых случаях затруднять чтение кода.
Ссылка для релевантности: godotengine / godot-предложения # 177
Довольно поздно для вечеринки, но как разработчик, который сильно полагается на метаданные и отражение при разработке плагинов, мне бы очень хотелось, чтобы аннотации стали частью Godot.
Хотя я действительно думаю, что это делает некоторые вещи более красивыми (например, экспорт и готовые материалы), мой главный аргумент был бы в пользу настраиваемых плагинов, которые могут использовать аннотации в полной мере.
Относительно ключевого слова onready
и его ограничений.
Я думаю, можно с уверенностью сказать, что большинство людей используют onready
для ранней инициализации ссылок на узлы. За исключением того, что это может оказаться невозможным без проблем в долгосрочной перспективе, потому что, когда вы создаете экземпляры некоторых сцен, которые зависят от _ready
, вы можете столкнуться с проблемой ссылки на null
:
func explode():
var bomb = preload("res://explosion.tscn").instance()
# Oops, forgot to `add_child(bomb)` earlier
bomb.fuse.wait_time = 5.0 # ERROR: fuse is `null`
add_child(bomb)
# ... because `fuse` is a $Timer node
# which is only initialized once added to the scene tree.
Конечно, вам нужно add_child()
экземпляр сцены, прежде чем пытаться установить fuse
, но что, если другие узлы / объекты должны знать точный предохранитель перед добавлением сцены в дерево сцены ?
Через некоторое время я нашел решение, описанное в https://github.com/godotengine/godot/issues/33620#issuecomment -559999681. Как вы можете заметить, onready
- это всего лишь NOTIFICATION_READY
, в то время как на самом деле мне нужно было NOTIFICATION_INSTANCED
и инициализировать мои ссылки еще раньше. Единственная проблема в том, что нет ключевого слова oninstanced
, и я думаю, вы можете понять, к чему я веду. 🙂
Итак, я думаю, было бы неплохо переделать ключевое слово onready
в качестве аннотации, а также поддержать некоторые другие угловые случаи (например, мой, как всегда!) С функциональностью @oninstanced
без раздувания языка сценариев , а также добавлена поддержка других уведомлений, относящихся к инициализации ( _init
, _enter_tree
и т. д.).
Связанное предложение: godotengine / годот-предложения № 260.
Открыто предложение с более конкретной информацией: https://github.com/godotengine/godot-proposals/issues/828
Заменено вышеуказанным предложением.
Самый полезный комментарий
Большинство (если не все) изменений синтаксиса GDScript совместимы со старым кодом. Основная цель - повысить продуктивность разработчиков с помощью GDScript, например:
match
позволяют использовать операторы switch-case (которые были весьма востребованы) и даже улучшают это, позволяя людям легко сопоставлять массивы и словари.onready
переменные (которые были нововведением в 2.x) конкретизируют шаблон, который часто использовался, а именно инициализацию переменных в_ready
.Это открытое сообщество. Разработчики игр могут прийти и высказать свое мнение, как и вы. В любом случае пройдет немало времени, прежде чем аннотации станут реальностью.
Если бы он уже был достаточно хорош, мы бы не получили для него запросы на добавление новых функций.
Синтаксис еще не доработан. Вполне вероятно, что он не заменит сразу ключевые слова
onready
иexport
.