{"id":378127,"date":"2024-06-05T21:00:17","date_gmt":"2024-06-05T21:00:17","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=378127"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=378127","title":{"rendered":"<span>AOP \u0432 Golang: \u043a\u0430\u043a \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u0432\u0430\u043c \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u044d\u0442\u043e\u0433\u043e \u0434\u0435\u043b\u0430\u0442\u044c<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/535\/55f\/63d\/53555f63dc16e35de3f8e7e6100dd068.png\" width=\"1280\" height=\"731\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/535\/55f\/63d\/53555f63dc16e35de3f8e7e6100dd068.png\"\/><\/figure>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! <em>Nikolaich &lt;&lt; in<\/em><\/p>\n<p>\u042f java-\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442 \u043f\u043e \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u0438 \u0438 <s>\u0430\u043b\u043a\u043e\u0433\u043e\u043b\u0438\u043a<\/s> go-developer \u043f\u043e \u0437\u043e\u0432\u0443 \u0434\u0443\u0448\u0438. \u0418 \u0432\u043e\u0442 \u0432 \u043e\u0434\u0438\u043d \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u044b\u0439 \u0434\u0435\u043d\u044c \u044f \u043f\u043e\u0434\u0443\u043c\u0430\u043b \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0440\u0430\u0437 \u0443\u0436 \u0432 Go \u0435\u0441\u0442\u044c \u043f\u0430\u043a\u0435\u0442 reflect, \u0442\u043e \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0410\u041e\u041f, \u043f\u0440\u044f\u043c\u043e \u043a\u0430\u043a \u0432 java. \u0415\u0441\u043b\u0438 \u0432\u043a\u0440\u0430\u0442\u0446\u0435, \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0435\u0440\u0442\u043a\u0438 \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u043a\u0440\u0430\u0441\u0438\u0432\u043e \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u043b\u043e\u0433\u0438, \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0438, \u0442\u0440\u0435\u0439\u0441\u0438\u043d\u0433\u0438, \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043e\u0434\u043d\u043e\u0442\u0438\u043f\u043d\u044b\u0435 \u0448\u0442\u0443\u043a\u0438, \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u0442\u0435\u043c, \u043a\u0430\u043a \u044f \u043f\u0440\u043e\u0434\u0435\u043b\u044b\u0432\u0430\u043b \u044d\u0442\u043e \u0432 java. <\/p>\n<p>\u0412\u043e\u0442 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 \u0434\u0436\u0430\u0432\u0430-\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0434\u0430 \u0442\u0430\u043a\u043e\u0439 \u043e\u0431\u0435\u0440\u0442\u043a\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>Java Spring AspectJ code<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component;  @Aspect @Component public class LoggingAspect {      @Around(\"execution(* ru.example.service.EmployeeService.*(..))\")     public Object aroundAdvice(       ProceedingJoinPoint joinPoint) throws Throwable {          \/\/ Custom logic before the method execution         logger.info(\"Before method execution\");          \/\/ Proceed with the actual method execution         Object result = joinPoint.proceed();          \/\/ Custom logic after the method execution         logger.info(\"After method execution\");          return result;     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u043b\u044f \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u0432\u0448\u0438\u0445\u0441\u044f \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e <a href=\"https:\/\/javarush.com\/groups\/posts\/3137-chto-takoe-aop-osnovih-aspektno-orientirovannogo-programmirovanija\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0443<\/a> \u0434\u043b\u044f \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0432 Spring AOP. \u0410 \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u043f\u043e\u043d\u044f\u043b <s>(\u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e\u0448\u043b\u0430 \u043e\u043d\u0430, \u044d\u0442\u0430 \u0432\u0430\u0448\u0430 java)<\/s> \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%90%D1%81%D0%BF%D0%B5%D0%BA%D1%82%D0%BD%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5\" rel=\"noopener noreferrer nofollow\">\u0432\u0438\u043a\u0438<\/a>, \u0447\u0442\u043e \u0437\u0430 \u0437\u0432\u0435\u0440\u044c \u0442\u0430\u043a\u043e\u0439 \u0410\u041e\u041f.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u043d\u0430\u0447\u043d\u0435\u043c \u0443\u0436\u0435 \u043a\u043e\u0434\u0438\u0442\u044c \u043d\u0430 Go! \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c\u0441\u044f \u0441 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u043e\u0439. \u041d\u0430 \u0432\u0445\u043e\u0434 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043e\u0431\u0435\u0440\u0442\u044b\u0432\u0430\u0435\u043c\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e funcIn, \u0430 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e funcOut, \u043d\u043e \u0441 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0438\u043c\u0438 \u0436\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438, \u043a\u0430\u043a funcIn. \u0412 \u044d\u0442\u043e\u043c \u043d\u0430\u043c \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438. \u0424\u0438\u0447\u0430 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0432 \u044f\u0437\u044b\u043a\u0435 \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 1.18, \u0438 \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439.<\/p>\n<pre><code class=\"go\">func wrapFunc[FuncType any](funcIn FuncType) (funcOut FuncType)<\/code><\/pre>\n<p>\u0412 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u044b\u0445 \u0441\u043a\u043e\u0431\u043a\u0430\u0445 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a <strong>[FuncType any]<\/strong>. \u0422\u043e \u0435\u0441\u0442\u044c \u043f\u043e \u0441\u0443\u0442\u0438 \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u0440\u0438\u043d\u044f\u0442\u044c any &#8212; \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e. \u0427\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u043a\u0442\u043e-\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0434\u0441\u0443\u043d\u0443\u0442\u044c \u043d\u0430 \u0432\u0445\u043e\u0434 \u043d\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0430 \u043a\u0430\u043a\u0443\u044e-\u043d\u0438\u0431\u0443\u0434\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0441\u0440\u0435\u0437 \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u0435\u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0432\u0435\u0449\u0438, \u043d\u043e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u043e\u0433\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443, \u0447\u0442\u043e\u0431\u044b FuncType \u0431\u044b\u043b \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439, \u044f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b&#8230; \u041d\u043e \u0447\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u043e &#8212; \u044d\u0442\u043e \u0442\u043e \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u044e funcIn \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0431\u044b\u0442\u044c \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0431\u0443\u0434\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f funcOut \u0441 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0438 \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0431\u0435\u0441\u0448\u043e\u0432\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u043c\u0435\u0441\u0442\u043e \u0441\u0442\u0430\u0440\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 &#8212; \u043d\u043e\u0432\u0443\u044e. \u0422\u0430\u043a \u043a\u0430\u043a \u0438 funcIn \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f FuncType, \u0438 funcOut \u0438\u043c\u0435\u0435\u0442 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u0442\u0438\u043f FuncType! (\u0425\u043e\u0442\u044c \u043c\u044b \u043f\u043e\u043a\u0430 \u0438 \u043d\u0435 \u0437\u043d\u0430\u0435\u043c, \u043a\u0430\u043a\u043e\u0439 \u0438\u043c\u0435\u043d\u043d\u043e)<\/p>\n<p>\u0410 \u0435\u0449\u0435 \u043d\u0430\u043c \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0432\u043e wrapFunc \u043e\u0431\u0435\u0440\u0442\u043a\u0443 wrapper \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 funcIn. wrapper &#8212; \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f. \u041d\u0430 \u0432\u0445\u043e\u0434 \u043e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u044f\u0442\u044c funcIn, \u0430 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 &#8212; \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0444\u043b\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043b\u044e\u0431\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 go, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0437\u0430\u0442\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u0432 <strong>reflect.MakeFunc<\/strong>, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e. \u0421\u0440\u0430\u0437\u0443 \u0437\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u0438\u043d\u043e\u043d\u0438\u043c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u0444\u043b\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"go\">type WrappedFunc = func(args []reflect.Value) []reflect.Value<\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435 WrappedFunc. \u0418\u0442\u0430\u043a, \u043a\u0430\u043a \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 wrapper:<\/p>\n<pre><code class=\"go\">func SimpleWrapper(funcIn any) WrappedFunc { return func(args []reflect.Value) []reflect.Value {       \/\/ \u0442\u0443\u0442 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043a\u043e\u0434 \u0414\u041e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f funcIn       results := aop.Proceed(funcIn, args) \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u0430\u043c\u0443 funcIn       \/\/ \u0442\u0443\u0442 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043a\u043e\u0434 \u041f\u041e\u0421\u041b\u0415 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f funcIn       return results \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f funcIn } }  \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043b\u044e\u0431\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e fptr \u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 args \/\/ \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \/\/ \u041e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u0442\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u0448\u044c, \u0447\u0442\u043e \u0437\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f  \/\/ \u0438 \u043a\u0430\u043a\u0438\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0435\/\u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b. \u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u0432\u0441\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u0442 \u0441\u0430\u043c\u0430 func Proceed(fptr any, args []reflect.Value) []reflect.Value { return reflect.ValueOf(fptr).Call(args) }<\/code><\/pre>\n<p>\u0418 \u0432\u043e\u0442 \u0442\u0430\u043a\u0443\u044e \u043e\u0431\u0435\u0440\u0442\u043a\u0443 wrapper \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u0434\u0441\u0443\u043d\u0443\u0442\u044c \u0432\u043e wrapFunc \u0432\u0442\u043e\u0440\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043a funcIn, \u0447\u0442\u043e\u0431\u044b \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0437\u0430\u0432\u0435\u0442\u043d\u0443\u044e funcOut.<\/p>\n<pre><code class=\"go\">func wrapFunc[FuncType any](   funcIn FuncType,   wrapper func(any) WrappedFunc, ) (funcOut FuncType) { fn := reflect.ValueOf(&amp;funcOut).Elem() \/\/ \u0431\u0435\u0440\u0435\u043c \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u043d\u0430 funcOut     \/\/ \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c WrappedFunc \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043d\u0430\u0448\u0435\u0439 funcIn,      \/\/ \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u0437 \u043d\u0435\u0435 \u043d\u043e\u0432\u0443\u044e \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u043d\u0435\u043a\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 rf2 := reflect.MakeFunc(fn.Type(), wrapper(funcIn))  fn.Set(rf2) \/\/ \u043f\u043e\u0434\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u0432 funcOut return \/\/ \u0443\u0440\u0430! \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u043e\u0432\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u043c\u0435\u0441\u0442\u043e \u0441\u0442\u0430\u0440\u043e\u0439 }<\/code><\/pre>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043a\u043e\u0434 \u043f\u0430\u043a\u0435\u0442\u0430 \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u0441 \u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0439 \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u0435\u0440\u0442\u043e\u043a \u043d\u0430\u0434 \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439. \u0418\u043b\u0438 \u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <\/p>\n<p><strong>go get <\/strong><a href=\"http:\/\/github.com\/alnpokrovsky\/go-aop\" rel=\"noopener noreferrer nofollow\"><strong>github.com\/alnpokrovsky\/go-aop<\/strong><\/a> <\/p>\n<details class=\"spoiler\">\n<summary>aop.go<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"go\">package aop  import ( \"fmt\" \"reflect\" \"runtime\" )  type WrappedFunc = func(args []reflect.Value) []reflect.Value  \/\/ WrapFunc returns new function with same signature as funcIn func \/\/ funcIn will be argument of every wrapper. \/\/ so you should manually call Proceed(fptr, args) \/\/ to get result of inner function inside wrapper func WrapFunc[FuncType any]( funcIn FuncType, wrappers ...func(any) WrappedFunc, ) (funcOut FuncType) { funcOut = funcIn for _, wrapper := range wrappers { funcOut = wrapFunc(funcOut, wrapper) } return }  func wrapFunc[FuncType any]( funcIn FuncType, wrapper func(any) WrappedFunc, ) (funcOut FuncType) { fn := reflect.ValueOf(&amp;funcOut).Elem() rf2 := reflect.MakeFunc(fn.Type(), wrapper(funcIn)) fn.Set(rf2) return }  \/\/ Proceed is usabale for wrapper, when you just want \/\/ to call wrapped func with provided arguments func Proceed(fptr any, args []reflect.Value) []reflect.Value { return reflect.ValueOf(fptr).Call(args) }  \/\/ IsImplements checks if reflectValue rv implements interface T func IsImplements[T any](rv reflect.Value) bool { return rv.Type().Implements(reflect.TypeOf((*T)(nil)).Elem()) }  \/\/ As casts reflectValue rv to your interface T func As[T any](rv reflect.Value) T { return rv.Interface().(T) }  \/\/ FuncName returns function name with it's argument and return types func FuncName(fn any) string { fnName := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name() fnType := reflect.TypeOf(fn).String() return fmt.Sprintf(\"%s %s\", fnName, fnType) } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0410 \u0435\u0449\u0435 \u043f\u0440\u0438\u043c\u0435\u0440 \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u043e\u0441\u0438\u0442 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440 \u0438 \u043d\u0435 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d \u043d\u0430 \u043f\u0440\u043e\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435.<\/p>\n<pre><code class=\"go\">var callsCounter = 0  func CleanWrapperCountAfter(fptr any) aop.WrappedFunc { return func(args []reflect.Value) []reflect.Value {         log.Println(aop.FuncName(fptr)) \/\/ \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0438\u043c\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c         results := aop.Proceed(fptr, args) \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e callsCounter++ \/\/ \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 return results } }  func main() {     wrappedFunc := aop.WrapFunc(func(a int, b int) int { return a + b }, CleanWrapperCountAfter, ) \/\/ \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043d\u043e\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e     c := wrappedFunc(1,2) \/\/ \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043b\u0438     log.Println(c) \/\/ \u043f\u0440\u043e\u0441\u0442\u043e \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0440\u0443\u0433\u0430\u043b\u0441\u044f \u043d\u0430 \u043d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435     log.Println(callsCounter) \/\/ \u043e \u0447\u0443\u0434\u043e, \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0440\u0430\u0432\u0435\u043d 1! }<\/code><\/pre>\n<p>\u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u0437\u0434\u043e\u0440\u043e\u0432\u043e! \u042f \u0438\u0437\u043e\u0431\u0440\u0435\u043b \u0410\u041e\u041f \u0432 golang. \u0417\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c \u043f\u043e\u0432\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0440\u0430\u0441\u0445\u043e\u0434\u0438\u043c\u0441\u044f \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u0438\u0442\u044c \u0438 \u0443\u043b\u0443\u0447\u0448\u0430\u0442\u044c \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u0434\u0430, \u043f\u043e\u043c\u0435\u0449\u0430\u044f \u0432\u0441\u044f\u043a\u0438\u0435 \u0442\u0440\u0435\u0439\u0441\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432 \u043e\u0431\u0435\u0440\u0442\u043a\u0438.<\/p>\n<hr\/>\n<p>\u041d\u043e&#8230; \u0435\u0441\u0442\u044c \u0432 \u044d\u0442\u043e\u0439 \u0431\u043e\u0447\u043a\u0435 \u043c\u0435\u0434\u0430 \u043b\u043e\u0436\u043a\u0430 \u0434\u0435\u0433\u0442\u044f. \u0418 \u044d\u0442\u043e &#8212; \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438. \u0422\u043e, \u0440\u0430\u0434\u0438 \u0447\u0435\u0433\u043e \u043b\u044e\u0434\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 go, \u0430 \u043d\u0435 java. Golang, \u043a\u0441\u0442\u0430\u0442\u0438, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0435\u043f\u043b\u043e\u0445\u0438\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u043e\u0432. \u0418\u043c\u0438 \u044f \u0438 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043e\u0446\u0435\u043d\u0438\u0442\u044c, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0435 \u043f\u043b\u043e\u0445\u043e.<\/p>\n<details class=\"spoiler\">\n<summary>aop_test.go<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"go\">package aop  import ( \"reflect\" \"testing\"  \"github.com\/stretchr\/testify\/assert\" )  var callsCounter = 0  func cleanWrapperCountAfter(fptr any) WrappedFunc { return func(args []reflect.Value) []reflect.Value { results := Proceed(fptr, args) \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e callsCounter++                 \/\/ \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 return results } }  \/\/ just to make sure it is working func TestSimpleWrapper(t *testing.T) { wrappedFunc := WrapFunc(func(a int, b int) int { return a + b }, cleanWrapperCountAfter, ) \/\/ \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043d\u043e\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e result := wrappedFunc(1, 2) \/\/ \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043b\u0438  assert.Equal(t, 3, result) assert.Equal(t, callsCounter, 1)  result = wrappedFunc(10, 20)  assert.Equal(t, 30, result) assert.Equal(t, callsCounter, 2) }  var simpleFunc = func(a int, b int) int { return a + b }  func BenchmarkNoReflection(b *testing.B) { for i := 0; i &lt; b.N; i++ { simpleFunc(1, 2) } }  var wrappedFunc = WrapFunc(simpleFunc, cleanWrapperCountAfter)  func BenchmarkWrappedFunc(b *testing.B) { for i := 0; i &lt; b.N; i++ { wrappedFunc(1, 2) } }  var twiceWrappedFunc = WrapFunc(simpleFunc, cleanWrapperCountAfter, cleanWrapperCountAfter)  func BenchmarkTwiceWrappedFunc(b *testing.B) { for i := 0; i &lt; b.N; i++ { twiceWrappedFunc(1, 2) } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c <strong>go test -bench=.<\/strong> \u0438 \u0443\u0436\u0430\u0441\u0430\u0435\u043c\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c \u0446\u0438\u0444\u0440\u0430\u043c<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/17a\/4cf\/340\/17a4cf3405f935fa7434f93b165985db.png\" alt=\"\u0423\u0436\u0430\u0441\u043d\u044b\u0435 \u0446\u0438\u0444\u0440\u044b\" title=\"\u0423\u0436\u0430\u0441\u043d\u044b\u0435 \u0446\u0438\u0444\u0440\u044b\" width=\"809\" height=\"215\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/17a\/4cf\/340\/17a4cf3405f935fa7434f93b165985db.png\"\/><\/p>\n<div><figcaption>\u0423\u0436\u0430\u0441\u043d\u044b\u0435 \u0446\u0438\u0444\u0440\u044b<\/figcaption><\/div>\n<\/figure>\n<p>\u041c\u044b \u0443\u0445\u0443\u0434\u0448\u0438\u043b\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 300 \u0440\u0430\u0437 (\u0441 0.9323ns\/op \u0434\u043e 273.7ns\/op) \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u043d\u043e\u0439 \u043e\u0431\u0435\u0440\u0442\u043a\u043e\u0439! \u0410 \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u0432\u0435, \u0442\u043e \u0443\u0436\u0435 \u0432 600 \u0440\u0430\u0437. \u041d\u0435 \u0441\u0430\u043c\u044b\u0435 \u043b\u0443\u0447\u0448\u0438\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043d\u0430 \u044f\u0437\u044b\u043a\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u043e\u0440\u0435\u0442\u0441\u044f \u0437\u0430 \u0437\u0432\u0430\u043d\u0438\u0435 <s>\u0434\u043e\u043c\u0430 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u043a\u0443\u043b\u044c\u0442\u0443\u0440\u044b \u0431\u044b\u0442\u0430<\/s> \u0442\u043e\u043f-10 \u043f\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \u041f\u043e\u0436\u0430\u043b\u0443\u0439, \u043c\u044b \u0438 \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f Go \u043a\u0430\u043a \u0440\u0430\u0437 \u0438\u0437-\u0437\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c, \u043d\u0430 \u043d\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p><strong>P.S.<\/strong> \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0438, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0439 \u043e\u0431\u0435\u0440\u0442\u043a\u0438 \u0443\u0445\u0443\u0434\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0435 \u0432 1000 \u0440\u0430\u0437, \u043a\u0430\u043a \u043c\u043e\u0433\u043b\u043e \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f, \u0430 \u043b\u0438\u0448\u044c \u043d\u0430 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 <strong>250-400ns<\/strong>(\u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043c\u0430\u0448\u0438\u043d\u044b), \u0447\u0442\u043e \u043f\u043e \u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e, \u043d\u043e \u0443\u0436\u0435 \u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u043c \u043a\u043e\u0448\u043c\u0430\u0440\u043e\u043c, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u0435\u0440\u0442\u043a\u0430 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0434 \u043f\u0440\u043e\u0436\u043e\u0440\u043b\u0438\u0432\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438 \u0442\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434. \u0410 \u0441\u0434\u0435\u043b\u0430\u044e\u0442 \u043b\u0438 \u043b\u0438\u0448\u043d\u0438\u0435 \u043f\u043e\u043b \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b \u043f\u043e\u0433\u043e\u0434\u0443 &#8212; \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u043d\u0430 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c. <\/p>\n<p><strong>P.P.S.<\/strong> \u0415\u0441\u043b\u0438 \u043a\u043e\u0433\u043e-\u0442\u043e \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043b\u043e, \u043a\u0430\u043a\u0438\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u044f \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u043b \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f, \u0438 \u043a\u0430\u043a \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f, \u0441\u0436\u0438\u0440\u0430\u0435\u043c\u043e\u0435 \u043e\u0431\u0435\u0440\u0442\u043a\u0430\u043c\u0438, &#8212; \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u044f \u043c\u043e\u0433 \u0431\u044b \u043f\u043e\u0441\u0432\u044f\u0442\u0438\u0442\u044c \u044d\u0442\u043e\u043c\u0443 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e. \u041f\u0438\u0448\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 &#171;\u0425\u043e\u0447\u0443 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435!&#187;.<\/p>\n<p><em>Nikolaich >> out<\/em><\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/819789\/\"> https:\/\/habr.com\/ru\/articles\/819789\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><\/figure>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! <em>Nikolaich &lt;&lt; in<\/em><\/p>\n<p>\u042f java-\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442 \u043f\u043e \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u0438 \u0438 <s>\u0430\u043b\u043a\u043e\u0433\u043e\u043b\u0438\u043a<\/s> go-developer \u043f\u043e \u0437\u043e\u0432\u0443 \u0434\u0443\u0448\u0438. \u0418 \u0432\u043e\u0442 \u0432 \u043e\u0434\u0438\u043d \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u044b\u0439 \u0434\u0435\u043d\u044c \u044f \u043f\u043e\u0434\u0443\u043c\u0430\u043b \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0440\u0430\u0437 \u0443\u0436 \u0432 Go \u0435\u0441\u0442\u044c \u043f\u0430\u043a\u0435\u0442 reflect, \u0442\u043e \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0410\u041e\u041f, \u043f\u0440\u044f\u043c\u043e \u043a\u0430\u043a \u0432 java. \u0415\u0441\u043b\u0438 \u0432\u043a\u0440\u0430\u0442\u0446\u0435, \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0435\u0440\u0442\u043a\u0438 \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u043a\u0440\u0430\u0441\u0438\u0432\u043e \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u043b\u043e\u0433\u0438, \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0438, \u0442\u0440\u0435\u0439\u0441\u0438\u043d\u0433\u0438, \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043e\u0434\u043d\u043e\u0442\u0438\u043f\u043d\u044b\u0435 \u0448\u0442\u0443\u043a\u0438, \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u0442\u0435\u043c, \u043a\u0430\u043a \u044f \u043f\u0440\u043e\u0434\u0435\u043b\u044b\u0432\u0430\u043b \u044d\u0442\u043e \u0432 java. <\/p>\n<p>\u0412\u043e\u0442 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 \u0434\u0436\u0430\u0432\u0430-\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0434\u0430 \u0442\u0430\u043a\u043e\u0439 \u043e\u0431\u0435\u0440\u0442\u043a\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>Java Spring AspectJ code<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component;  @Aspect @Component public class LoggingAspect {      @Around(\"execution(* ru.example.service.EmployeeService.*(..))\")     public Object aroundAdvice(       ProceedingJoinPoint joinPoint) throws Throwable {          \/\/ Custom logic before the method execution         logger.info(\"Before method execution\");          \/\/ Proceed with the actual method execution         Object result = joinPoint.proceed();          \/\/ Custom logic after the method execution         logger.info(\"After method execution\");          return result;     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u043b\u044f \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u0432\u0448\u0438\u0445\u0441\u044f \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e <a href=\"https:\/\/javarush.com\/groups\/posts\/3137-chto-takoe-aop-osnovih-aspektno-orientirovannogo-programmirovanija\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0443<\/a> \u0434\u043b\u044f \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0432 Spring AOP. \u0410 \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u043f\u043e\u043d\u044f\u043b <s>(\u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e\u0448\u043b\u0430 \u043e\u043d\u0430, \u044d\u0442\u0430 \u0432\u0430\u0448\u0430 java)<\/s> \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%90%D1%81%D0%BF%D0%B5%D0%BA%D1%82%D0%BD%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5\" rel=\"noopener noreferrer nofollow\">\u0432\u0438\u043a\u0438<\/a>, \u0447\u0442\u043e \u0437\u0430 \u0437\u0432\u0435\u0440\u044c \u0442\u0430\u043a\u043e\u0439 \u0410\u041e\u041f.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u043d\u0430\u0447\u043d\u0435\u043c \u0443\u0436\u0435 \u043a\u043e\u0434\u0438\u0442\u044c \u043d\u0430 Go! \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c\u0441\u044f \u0441 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u043e\u0439. \u041d\u0430 \u0432\u0445\u043e\u0434 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043e\u0431\u0435\u0440\u0442\u044b\u0432\u0430\u0435\u043c\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e funcIn, \u0430 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e funcOut, \u043d\u043e \u0441 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0438\u043c\u0438 \u0436\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438, \u043a\u0430\u043a funcIn. \u0412 \u044d\u0442\u043e\u043c \u043d\u0430\u043c \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438. \u0424\u0438\u0447\u0430 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0432 \u044f\u0437\u044b\u043a\u0435 \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 1.18, \u0438 \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439.<\/p>\n<pre><code class=\"go\">func wrapFunc[FuncType any](funcIn FuncType) (funcOut FuncType)<\/code><\/pre>\n<p>\u0412 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u044b\u0445 \u0441\u043a\u043e\u0431\u043a\u0430\u0445 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a <strong>[FuncType any]<\/strong>. \u0422\u043e \u0435\u0441\u0442\u044c \u043f\u043e \u0441\u0443\u0442\u0438 \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u0440\u0438\u043d\u044f\u0442\u044c any &#8212; \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e. \u0427\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u043a\u0442\u043e-\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0434\u0441\u0443\u043d\u0443\u0442\u044c \u043d\u0430 \u0432\u0445\u043e\u0434 \u043d\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0430 \u043a\u0430\u043a\u0443\u044e-\u043d\u0438\u0431\u0443\u0434\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0441\u0440\u0435\u0437 \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u0435\u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0432\u0435\u0449\u0438, \u043d\u043e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u043e\u0433\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443, \u0447\u0442\u043e\u0431\u044b FuncType \u0431\u044b\u043b \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439, \u044f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b&#8230; \u041d\u043e \u0447\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u043e &#8212; \u044d\u0442\u043e \u0442\u043e \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u044e funcIn \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0431\u044b\u0442\u044c \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0431\u0443\u0434\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f funcOut \u0441 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0438 \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0431\u0435\u0441\u0448\u043e\u0432\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u043c\u0435\u0441\u0442\u043e \u0441\u0442\u0430\u0440\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 &#8212; \u043d\u043e\u0432\u0443\u044e. \u0422\u0430\u043a \u043a\u0430\u043a \u0438 funcIn \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f FuncType, \u0438 funcOut \u0438\u043c\u0435\u0435\u0442 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u0442\u0438\u043f FuncType! (\u0425\u043e\u0442\u044c \u043c\u044b \u043f\u043e\u043a\u0430 \u0438 \u043d\u0435 \u0437\u043d\u0430\u0435\u043c, \u043a\u0430\u043a\u043e\u0439 \u0438\u043c\u0435\u043d\u043d\u043e)<\/p>\n<p>\u0410 \u0435\u0449\u0435 \u043d\u0430\u043c \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0432\u043e wrapFunc \u043e\u0431\u0435\u0440\u0442\u043a\u0443 wrapper \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 funcIn. wrapper &#8212; \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f. \u041d\u0430 \u0432\u0445\u043e\u0434 \u043e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u044f\u0442\u044c funcIn, \u0430 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 &#8212; \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0444\u043b\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043b\u044e\u0431\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 go, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0437\u0430\u0442\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u0432 <strong>reflect.MakeFunc<\/strong>, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e. \u0421\u0440\u0430\u0437\u0443 \u0437\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u0438\u043d\u043e\u043d\u0438\u043c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u0444\u043b\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"go\">type WrappedFunc = func(args []reflect.Value) []reflect.Value<\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435 WrappedFunc. \u0418\u0442\u0430\u043a, \u043a\u0430\u043a \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 wrapper:<\/p>\n<pre><code class=\"go\">func SimpleWrapper(funcIn any) WrappedFunc { return func(args []reflect.Value) []reflect.Value {       \/\/ \u0442\u0443\u0442 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043a\u043e\u0434 \u0414\u041e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f funcIn       results := aop.Proceed(funcIn, args) \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u0430\u043c\u0443 funcIn       \/\/ \u0442\u0443\u0442 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043a\u043e\u0434 \u041f\u041e\u0421\u041b\u0415 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f funcIn       return results \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f funcIn } }  \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043b\u044e\u0431\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e fptr \u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 args \/\/ \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \/\/ \u041e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u0442\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u0448\u044c, \u0447\u0442\u043e \u0437\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f  \/\/ \u0438 \u043a\u0430\u043a\u0438\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0435\/\u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b. \u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u0432\u0441\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u0442 \u0441\u0430\u043c\u0430 func Proceed(fptr any, args []reflect.Value) []reflect.Value { return reflect.ValueOf(fptr).Call(args) }<\/code><\/pre>\n<p>\u0418 \u0432\u043e\u0442 \u0442\u0430\u043a\u0443\u044e \u043e\u0431\u0435\u0440\u0442\u043a\u0443 wrapper \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u0434\u0441\u0443\u043d\u0443\u0442\u044c \u0432\u043e wrapFunc \u0432\u0442\u043e\u0440\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043a funcIn, \u0447\u0442\u043e\u0431\u044b \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0437\u0430\u0432\u0435\u0442\u043d\u0443\u044e funcOut.<\/p>\n<pre><code class=\"go\">func wrapFunc[FuncType any](   funcIn FuncType,   wrapper func(any) WrappedFunc, ) (funcOut FuncType) { fn := reflect.ValueOf(&amp;funcOut).Elem() \/\/ \u0431\u0435\u0440\u0435\u043c \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u043d\u0430 funcOut     \/\/ \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c WrappedFunc \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043d\u0430\u0448\u0435\u0439 funcIn,      \/\/ \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u0437 \u043d\u0435\u0435 \u043d\u043e\u0432\u0443\u044e \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u043d\u0435\u043a\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 rf2 := reflect.MakeFunc(fn.Type(), wrapper(funcIn))  fn.Set(rf2) \/\/ \u043f\u043e\u0434\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u0432 funcOut return \/\/ \u0443\u0440\u0430! \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u043e\u0432\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u043c\u0435\u0441\u0442\u043e \u0441\u0442\u0430\u0440\u043e\u0439 }<\/code><\/pre>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043a\u043e\u0434 \u043f\u0430\u043a\u0435\u0442\u0430 \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u0441 \u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0439 \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u0435\u0440\u0442\u043e\u043a \u043d\u0430\u0434 \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439. \u0418\u043b\u0438 \u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <\/p>\n<p><strong>go get <\/strong><a href=\"http:\/\/github.com\/alnpokrovsky\/go-aop\" rel=\"noopener noreferrer nofollow\"><strong>github.com\/alnpokrovsky\/go-aop<\/strong><\/a> <\/p>\n<details class=\"spoiler\">\n<summary>aop.go<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"go\">package aop  import ( \"fmt\" \"reflect\" \"runtime\" )  type WrappedFunc = func(args []reflect.Value) []reflect.Value  \/\/ WrapFunc returns new function with same signature as funcIn func \/\/ funcIn will be argument of every wrapper. \/\/ so you should manually call Proceed(fptr, args) \/\/ to get result of inner function inside wrapper func WrapFunc[FuncType any]( funcIn FuncType, wrappers ...func(any) WrappedFunc, ) (funcOut FuncType) { funcOut = funcIn for _, wrapper := range wrappers { funcOut = wrapFunc(funcOut, wrapper) } return }  func wrapFunc[FuncType any]( funcIn FuncType, wrapper func(any) WrappedFunc, ) (funcOut FuncType) { fn := reflect.ValueOf(&amp;funcOut).Elem() rf2 := reflect.MakeFunc(fn.Type(), wrapper(funcIn)) fn.Set(rf2) return }  \/\/ Proceed is usabale for wrapper, when you just want \/\/ to call wrapped func with provided arguments func Proceed(fptr any, args []reflect.Value) []reflect.Value { return reflect.ValueOf(fptr).Call(args) }  \/\/ IsImplements checks if reflectValue rv implements interface T func IsImplements[T any](rv reflect.Value) bool { return rv.Type().Implements(reflect.TypeOf((*T)(nil)).Elem()) }  \/\/ As casts reflectValue rv to your interface T func As[T any](rv reflect.Value) T { return rv.Interface().(T) }  \/\/ FuncName returns function name with it's argument and return types func FuncName(fn any) string { fnName := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name() fnType := reflect.TypeOf(fn).String() return fmt.Sprintf(\"%s %s\", fnName, fnType) } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0410 \u0435\u0449\u0435 \u043f\u0440\u0438\u043c\u0435\u0440 \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u043e\u0441\u0438\u0442 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440 \u0438 \u043d\u0435 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d \u043d\u0430 \u043f\u0440\u043e\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435.<\/p>\n<pre><code class=\"go\">var callsCounter = 0  func CleanWrapperCountAfter(fptr any) aop.WrappedFunc { return func(args []reflect.Value) []reflect.Value {         log.Println(aop.FuncName(fptr)) \/\/ \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0438\u043c\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c         results := aop.Proceed(fptr, args) \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e callsCounter++ \/\/ \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 return results } }  func main() {     wrappedFunc := aop.WrapFunc(func(a int, b int) int { return a + b }, CleanWrapperCountAfter, ) \/\/ \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043d\u043e\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e     c := wrappedFunc(1,2) \/\/ \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043b\u0438     log.Println(c) \/\/ \u043f\u0440\u043e\u0441\u0442\u043e \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0440\u0443\u0433\u0430\u043b\u0441\u044f \u043d\u0430 \u043d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435     log.Println(callsCounter) \/\/ \u043e \u0447\u0443\u0434\u043e, \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0440\u0430\u0432\u0435\u043d 1! }<\/code><\/pre>\n<p>\u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u0437\u0434\u043e\u0440\u043e\u0432\u043e! \u042f \u0438\u0437\u043e\u0431\u0440\u0435\u043b \u0410\u041e\u041f \u0432 golang. \u0417\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c \u043f\u043e\u0432\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0440\u0430\u0441\u0445\u043e\u0434\u0438\u043c\u0441\u044f \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u0438\u0442\u044c \u0438 \u0443\u043b\u0443\u0447\u0448\u0430\u0442\u044c \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u0434\u0430, \u043f\u043e\u043c\u0435\u0449\u0430\u044f \u0432\u0441\u044f\u043a\u0438\u0435 \u0442\u0440\u0435\u0439\u0441\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432 \u043e\u0431\u0435\u0440\u0442\u043a\u0438.<\/p>\n<hr\/>\n<p>\u041d\u043e&#8230; \u0435\u0441\u0442\u044c \u0432 \u044d\u0442\u043e\u0439 \u0431\u043e\u0447\u043a\u0435 \u043c\u0435\u0434\u0430 \u043b\u043e\u0436\u043a\u0430 \u0434\u0435\u0433\u0442\u044f. \u0418 \u044d\u0442\u043e &#8212; \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438. \u0422\u043e, \u0440\u0430\u0434\u0438 \u0447\u0435\u0433\u043e \u043b\u044e\u0434\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 go, \u0430 \u043d\u0435 java. Golang, \u043a\u0441\u0442\u0430\u0442\u0438, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0435\u043f\u043b\u043e\u0445\u0438\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u043e\u0432. \u0418\u043c\u0438 \u044f \u0438 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043e\u0446\u0435\u043d\u0438\u0442\u044c, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0435 \u043f\u043b\u043e\u0445\u043e.<\/p>\n<details class=\"spoiler\">\n<summary>aop_test.go<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"go\">package aop  import ( \"reflect\" \"testing\"  \"github.com\/stretchr\/testify\/assert\" )  var callsCounter = 0  func cleanWrapperCountAfter(fptr any) WrappedFunc { return func(args []reflect.Value) []reflect.Value { results := Proceed(fptr, args) \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e callsCounter++                 \/\/ \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 return results } }  \/\/ just to make sure it is working func TestSimpleWrapper(t *testing.T) { wrappedFunc := WrapFunc(func(a int, b int) int { return a + b }, cleanWrapperCountAfter, ) \/\/ \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043d\u043e\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e result := wrappedFunc(1, 2) \/\/ \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043b\u0438  assert.Equal(t, 3, result) assert.Equal(t, callsCounter, 1)  result = wrappedFunc(10, 20)  assert.Equal(t, 30, result) assert.Equal(t, callsCounter, 2) }  var simpleFunc = func(a int, b int) int { return a + b }  func BenchmarkNoReflection(b *testing.B) { for i := 0; i &lt; b.N; i++ { simpleFunc(1, 2) } }  var wrappedFunc = WrapFunc(simpleFunc, cleanWrapperCountAfter)  func BenchmarkWrappedFunc(b *testing.B) { for i := 0; i &lt; b.N; i++ { wrappedFunc(1, 2) } }  var twiceWrappedFunc = WrapFunc(simpleFunc, cleanWrapperCountAfter, cleanWrapperCountAfter)  func BenchmarkTwiceWrappedFunc(b *testing.B) { for i := 0; i &lt; b.N; i++ { twiceWrappedFunc(1, 2) } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c <strong>go test -bench=.<\/strong> \u0438 \u0443\u0436\u0430\u0441\u0430\u0435\u043c\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c \u0446\u0438\u0444\u0440\u0430\u043c<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0423\u0436\u0430\u0441\u043d\u044b\u0435 \u0446\u0438\u0444\u0440\u044b<\/figcaption><\/div>\n<\/figure>\n<p>\u041c\u044b \u0443\u0445\u0443\u0434\u0448\u0438\u043b\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 300 \u0440\u0430\u0437 (\u0441 0.9323ns\/op \u0434\u043e 273.7ns\/op) \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u043d\u043e\u0439 \u043e\u0431\u0435\u0440\u0442\u043a\u043e\u0439! \u0410 \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u0432\u0435, \u0442\u043e \u0443\u0436\u0435 \u0432 600 \u0440\u0430\u0437. \u041d\u0435 \u0441\u0430\u043c\u044b\u0435 \u043b\u0443\u0447\u0448\u0438\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043d\u0430 \u044f\u0437\u044b\u043a\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u043e\u0440\u0435\u0442\u0441\u044f \u0437\u0430 \u0437\u0432\u0430\u043d\u0438\u0435 <s>\u0434\u043e\u043c\u0430 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u043a\u0443\u043b\u044c\u0442\u0443\u0440\u044b \u0431\u044b\u0442\u0430<\/s> \u0442\u043e\u043f-10 \u043f\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \u041f\u043e\u0436\u0430\u043b\u0443\u0439, \u043c\u044b \u0438 \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f Go \u043a\u0430\u043a \u0440\u0430\u0437 \u0438\u0437-\u0437\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c, \u043d\u0430 \u043d\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p><strong>P.S.<\/strong> \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0438, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0439 \u043e\u0431\u0435\u0440\u0442\u043a\u0438 \u0443\u0445\u0443\u0434\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0435 \u0432 1000 \u0440\u0430\u0437, \u043a\u0430\u043a \u043c\u043e\u0433\u043b\u043e \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f, \u0430 \u043b\u0438\u0448\u044c \u043d\u0430 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 <strong>250-400ns<\/strong>(\u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043c\u0430\u0448\u0438\u043d\u044b), \u0447\u0442\u043e \u043f\u043e \u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e, \u043d\u043e \u0443\u0436\u0435 \u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u043c \u043a\u043e\u0448\u043c\u0430\u0440\u043e\u043c, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u0435\u0440\u0442\u043a\u0430 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0434 \u043f\u0440\u043e\u0436\u043e\u0440\u043b\u0438\u0432\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438 \u0442\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434. \u0410 \u0441\u0434\u0435\u043b\u0430\u044e\u0442 \u043b\u0438 \u043b\u0438\u0448\u043d\u0438\u0435 \u043f\u043e\u043b \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b \u043f\u043e\u0433\u043e\u0434\u0443 &#8212; \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u043d\u0430 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c. <\/p>\n<p><strong>P.P.S.<\/strong> \u0415\u0441\u043b\u0438 \u043a\u043e\u0433\u043e-\u0442\u043e \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043b\u043e, \u043a\u0430\u043a\u0438\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u044f \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u043b \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f, \u0438 \u043a\u0430\u043a \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f, \u0441\u0436\u0438\u0440\u0430\u0435\u043c\u043e\u0435 \u043e\u0431\u0435\u0440\u0442\u043a\u0430\u043c\u0438, &#8212; \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u044f \u043c\u043e\u0433 \u0431\u044b \u043f\u043e\u0441\u0432\u044f\u0442\u0438\u0442\u044c \u044d\u0442\u043e\u043c\u0443 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e. \u041f\u0438\u0448\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 &#171;\u0425\u043e\u0447\u0443 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435!&#187;.<\/p>\n<p><em>Nikolaich >> out<\/em><\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!--<\/div>\n\n\n<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-378127","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/378127","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=378127"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/378127\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=378127"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=378127"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=378127"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}