@dlangru

Страница 73 из 719
Oleg
18.09.2016
19:43:39
попробуй сначала предложить сам такие ситуации

Макс
18.09.2016
20:25:40
ой

Сорри, не сюда

Dmitry
20.09.2016
13:17:25
А в чем разница между functionAttributes https://dlang.org/phobos/std_traits.html#functionAttributes И getAttributes которая вызывается через __traits __traits(getAttributes, Person.name)

Google
Dmitry
20.09.2016
13:18:52
один для функции, другой для класса чтоли?

Eto
20.09.2016
13:20:45
functionAttributes использует внутри __traits(getFunctionAttributes.

Dmitry
20.09.2016
13:26:43
второе это именно языковая фича, а первое библиотечная так?

Просто я не пойму почему в std.traits есть: SetFunctionAttributes но нет GetFunctionAttributes

где логика?

Eto
20.09.2016
13:33:49
Разве funtionAttributes не выполняет функционал второго?

Dmitry
20.09.2016
13:38:29
это дублирующийся функционал получается?

Anatoly
20.09.2016
13:39:14
ну некоторым кажется, что дёргать __traits в коде конечного погромца - как-то не очень

Grigirii
20.09.2016
13:39:26
functionAttributes = атрибуты функции, такие как nothrow, а attributes - UDA

Anatoly
20.09.2016
13:39:40
хм

Dmitry
20.09.2016
13:39:53
а...

Anatoly
20.09.2016
13:40:04
я думал мы про getFunctionAttributes

Dmitry
20.09.2016
13:41:20
так, а в чем разница тогда: getUDAs и GetFunctionAttributes второе же тоже про UDA

Google
Dmitry
20.09.2016
13:51:22
а могу я сделать так: A a = new A(); foreach (x; Fields(a)) { writeln(x); }

еслb что я про https://dlang.org/phobos/std_traits.html#Fields

Grigirii
20.09.2016
13:52:55
на самом последнем dmd да

Dmitry
20.09.2016
13:53:25
` Error: template std.traits.Fields cannot deduce function from argument types !()(A), candidates are: C:\D\dmd2\windows\bin\..\..\src\phobos\std\traits.d(2174,1): std.traits.Fields(T)`

Grigirii
20.09.2016
13:54:07
значит A, а не a. Ему тип нужен

Dmitry
20.09.2016
13:54:36
а самый последний это какой? у меня v2.071.1

Grigirii
20.09.2016
13:55:28
2.071.2, в нём баг с этим foreach фиксили

до этого он работал только в рантайме

сегодня зарелизили

Dmitry
20.09.2016
13:56:03
foreach (x; Fields(A)) Error: cannot pass type A as a function argument это может быть следиствием бага? Щас обновлюсь

Grigirii
20.09.2016
13:56:37
нет, надо Fields!A

это же шаблонный аргумент

Dmitry
20.09.2016
13:57:30
Все шаблоны передаются через восклицательный так?

Grigirii
20.09.2016
13:58:46
да

Dmitry
20.09.2016
14:00:44
foreach (x; Fields!A) { writeln(x); } ругается на writeln: Error: cannot pass type string as a function argument

Grigirii
20.09.2016
14:02:21
ну да, x - тип, а не значение. если хочешь итерироваться по именам полей юзай FieldNameTuple

что интересно, на старом dmd компилится и работает в рантайме

Dmitry
20.09.2016
14:03:26
а так можно? foreach (x; (Fields!A).tupleof)

на старом это на каком?

Grigirii
20.09.2016
14:04:03
v2.070.0

Google
Dmitry
20.09.2016
14:08:30
а почему этот вариант не работает то? writeln(to!string(x)); Ведь под идее у типа есть строковое представление

а он ругается: Error: cannot pass type string as a function argument

вариант с FieldNameTuple работает

м... а как вообще типы представляются? как я понял у них нет строкового представления

Grigirii
20.09.2016
14:20:06
writeln(A.stringof); //output: A

Dmitry
20.09.2016
14:21:19
и кстати про шаблоны вопрос. Вот допустим возвращаемый тип указан как template как понять какие операции над ним можно сделать? Как я понимаю можно сделать так: auto foo = MySuperTemplate!x и вы получим результат в foo

Grigirii
20.09.2016
14:24:05
в основном по доке. просто есть соглашения на то, что бывает резултатом чего, как например range

ещё может быть указан контракт, если это результат функции

в случае MySuperTemplate!x это чаще всего просто класс, в который можно зайти и посмотреть. Fields здесь скорее исключение

Dmitry
20.09.2016
14:25:07
контракт это что? как он выглядит? в плане куда смотреть чтобы по доке понять

Grigirii
20.09.2016
14:26:10
в доке это обычно словами. контракт это секция in или out в теле функции. в доку вроде не выносится автоматически

Dmitry
20.09.2016
14:26:54
это входные выходные данные ?

Grigirii
20.09.2016
14:26:57
сейчас тулы автокомплита не очень умные, но вообще автокомплит в процессе кодинга в таких ситуациях хорошо помогают

это ограничения на вход и выход

обычно там ограничения на значения, например, что аргумент должен быть сортированным массивом, а не чем попало. это дока и проверка в дебажной сборке. про них есть глава в любой книге

в Александреску это "Контрактное программирование"

Dmitry
20.09.2016
14:29:04
понял, спасибо

Sergey
21.09.2016
06:52:27
Здравствуйте. Кто-нибудь сталкивался с функцией move для структур? Наткнулся на странную ситуацию, которую никак не могу понять

Max
21.09.2016
06:58:23
Саму ситуацию-то опиши

Sergey
21.09.2016
07:00:02
сейчас

Google
Sergey
21.09.2016
07:01:14
import std.stdio; import std.conv; import std.algorithm; void main() { Point p1 = Point(10,5); Point p2 = p1; p1.system.name = "B"; writeln("p1 = ", p1); writeln("p2 = ", p2); writeln("---"); write("p2 "); AnalyzePoint(move(p2)); writeln("p2 init = ", p2); //Point(0, 0, B) - судя по всему, за исходное значение для system //берется переданное при Point p2 = p1; т.е. оно было у p2 //до вызова this(this) //далее видно, что p2.system указывает на тот же объект, что и p1.system p1.system.name = "C"; writeln("p2 =", p2); } void AnalyzePoint(Point p) { write("moved "); writeln(p); } struct Point { int x; int y; // System system=new System("A"); this(this) { system = system.dup; } } class System { string name; this(string name) { this.name= name; } this() { this("Default"); } override string toString() { return name; } System dup() { return new System(name); } }

p1 = Point(10, 5, B) p2 = Point(10, 5, A) —- p2 moved Point(10, 5, A) p2 init = Point(0, 0, B) p2 =Point(0, 0, C)

пример синтетический

Одним из полей структуры является объект класса. для полного копирования структуры, используется конструктор this(this) После копирования объекта структуры, убеждаюсь, что p1 и p2 независимы. Затем перемещаю объект структуры в функцию AnalyzePoint(move(p2)); оставшийся идентификатор p2 в теле main должен быть заново инициализирован, поэтому я ожидаю если не p2.system.name == “A”, то хотябы p2.system == null но вижу, то, что описал в комментарии в коде

Max
21.09.2016
07:21:17
Почитай про .init – после вызова move восстанавливаются дефолтные значения для структуры, без вызова конструктора

Sergey
21.09.2016
07:22:10
читать-то я читал. Не могу понять, почему дефолтным значением структуры стало значение, переданное при копировании

p2 init = Point(0, 0, B) вот это значение B - его нигде нет в дефолтах. Его я проставил для p1 p1.system.name = "B"; перед копированием Point p2 = p1;

т.е. дефолтным для p2.system внезапно стало значение, которое было скопировано из p1

подправил описание. Написано сумбурно, попытаюсь еще раз соль выделить: Вот, допустим, такая структура struct Point { int x; int y=10; System system=new System("A"); .... } тогда, вроде бы, всегда результатом init должно становиться x==0, y==10, system.name =="А" в моем, получилось system.name =="B", и ранее я написал, откуда взялось это значение. Непонятно, почему оно взялось

Admin
ERROR: S client not available

Oleg
21.09.2016
08:04:51
в последнем варианте есть косячок

там выходит, что ты создаёшь память для system и её же меняешь

заново она не создаётся

Sergey
21.09.2016
08:10:26
честно сказать, не понял, о чем речь

Oleg
21.09.2016
08:12:39
1 сек

import std.stdio; class Sys { string name; this(string name) { this.name = name; } override string toString() { return "Sys("~name~")"; } } struct A { int x=10; Sys sys = new Sys("in struct"); this(this) { sys = new Sys(sys.name); } } void main() { A a; A b; writeln(a); writeln(b); a.sys.name = "xxx"; writeln(); writeln(a); writeln(b); }

на момент последнего вывода sys у 'a' и 'b' один и тот же

Sergey
21.09.2016
08:14:08
в данном примере - да

но у меня-то нет

Oleg
21.09.2016
08:14:29
struct Point { int x; int y=10; System system=new System("A"); .... }

Google
Sergey
21.09.2016
08:14:53
это просто пример, в котором есть "..."

обращал внимание на дефолтные значения

а тело структуры опустил

но в рабочем исходнике есть this(this)

Oleg
21.09.2016
08:15:45
я про инициализацию полей структуры

Sergey
21.09.2016
08:16:20
вот соответсвующий кусок кода struct Point { int x; int y; // System system=new System("A"); this(this) { system = system.dup; } }

Oleg
21.09.2016
08:16:45
если класс создаётся не в конструкторе, а как init значение, он будет разделён между всеми структурами

Sergey
21.09.2016
08:16:59
соответсвенно, при копировании объекта этой структуры, будет объект класса будет клонирован

Oleg
21.09.2016
08:17:23
метод dup переопределён в классе?

ну хотя не работало бы иначе

Sergey
21.09.2016
08:17:47
да, переопределен

Oleg
21.09.2016
08:18:57
по всей видимости move не копирует объект

всмысле не вызывает конструктор копирования

Sergey
21.09.2016
08:19:23
да. в этом его смысл

но значение p2 появилось ранее в результате копирования

затем уже было перемещено в функцию с помощью move

а для идентификатора p2 в main была вызвана Init (т.е. новый объект создан), насколько я понял из описания move

Oleg
21.09.2016
08:31:05
init значение для поля не новый класс, а старый, созданный в самом начале

это же адресс

там вызывается memcpy для объектов

и потом в один из объектов присваивается init

Sergey
21.09.2016
08:34:24
можно так выразиться: когда я копирую объект структуры, то его init значения переписываются?

Страница 73 из 719